*/
#![allow(dead_code)]
-use crate::dav::session::Session;
+use std::ffi::{c_char, c_int, CString};
+use crate::dav::ffi::{CxString, DavQLStatement, DavResult, DavSession};
+use crate::dav::resource::Resource;
+use crate::dav::session::{DavError, Session};
+use crate::dav::utils::cstr2str;
pub struct DavQuery {
pub from: String,
pub properties: Vec<String>,
- pub filter: Vec<String>,
+ pub filter: Option<String>,
pub depth: u16
}
DavQuery {
from: from.to_string(),
properties: Vec::new(),
- filter: Vec::new(),
+ filter: None,
depth: 1
}
}
self
}
- pub fn filter(&mut self, filter: Cmp) -> &mut Self {
- self.filter.push(filter.cmp);
+ pub fn filter(&mut self, filter: &str) -> &mut Self {
+ self.filter = Some(filter.to_string());
self
}
-}
+ pub fn execute<'a>(&self, session: &Session) -> Result<Resource<'a>, DavError> {
+ let query = self.compile();
+ let cxstr = CxString::new(query.as_str());
-pub struct Cmp {
- cmp: String,
-}
+ unsafe {
+ let stmt = dav_parse_statement(cxstr);
+ let errrorcode = dav_sql_statement_get_errorcode(stmt);
+ let result = if errrorcode != 0 {
+ let errrorcode = dav_sql_statement_get_errorcode(stmt);
+ let errormsg = cstr2str(dav_sql_statement_get_errormessage(stmt));
+ Err(DavError::QlError(format!("{} {}", errrorcode, errormsg)))
+ } else {
+ let stmt_result = dav_statement_exec(session.ptr, stmt);
+ if stmt_result.status == 0 && !stmt_result.result.is_null() {
+ Ok(Resource::from_ptr(stmt_result.result))
+ } else {
+ Err(session.get_error())
+ }
+ };
+ dav_free_statement(stmt);
+ result
+ }
+ }
+
+ fn compile(&self) -> String {
+ let properties = self
+ .properties
+ .iter()
+ .map(|p| format!("`{}`", p))
+ .collect::<Vec<_>>()
+ .join(", ");
+ let mut query = format!(
+ "select {} from {} with depth {}",
+ properties, self.from, self.depth
+ );
-impl Cmp {
- pub fn eq_str(prop: &str, str: &str) -> Cmp {
- Cmp {
- cmp: format!("{} = '{}'", prop, str),
+ if let Some(filter) = &self.filter {
+ query.push_str(" where ");
+ query.push_str(filter);
}
+
+ query
}
-}
\ No newline at end of file
+}
+
+unsafe extern "C" {
+ fn dav_parse_statement(stmt: CxString) -> *mut DavQLStatement;
+ fn dav_free_statement(stmt: *mut DavQLStatement);
+ fn dav_sql_statement_get_errorcode(stmt: *const DavQLStatement) -> c_int;
+ fn dav_sql_statement_get_errormessage(stmt: *const DavQLStatement) -> *mut c_char;
+ fn dav_statement_exec(sn: *mut DavSession, st: *mut DavQLStatement, ...) -> DavResult;
+}
pub base: ResourceRef<'a>
}
+impl Resource<'_> {
+ pub fn from_ptr<'a>(ptr: *mut ffi::DavResource) -> Resource<'a> {
+ Resource {
+ base: ResourceRef {
+ ptr: ptr,
+ _marker: PhantomData,
+ }
+ }
+ }
+
+ pub fn new<'a>(sn: &Session, path: &str) -> Resource<'a> {
+ let path = CString::new(path).unwrap();
+ unsafe {
+ let res = dav_resource_new(sn.ptr, path.as_ptr());
+ Resource::from_ptr(res)
+ }
+ }
+}
+
pub struct ResourceRef<'a> {
pub ptr: *mut ffi::DavResource,
_marker: PhantomData<&'a Resource<'a>>,
ffi::DavError::DavCouldntConnect => DavError::CouldntConnect,
ffi::DavError::DavTimeout => DavError::Timeout,
ffi::DavError::DavSslError => DavError::SslError,
- ffi::DavError::DavQlError => DavError::QlError,
+ ffi::DavError::DavQlError => DavError::QlError("".to_string()),
ffi::DavError::DavContentVerificationError => DavError::ContentVerificationError,
ffi::DavError::DavPreconditionFailed => DavError::PreconditionFailed,
ffi::DavError::DavRequestEntityTooLarge => DavError::RequestEntityTooLarge,
CouldntConnect,
Timeout,
SslError,
- QlError,
+ QlError(String),
ContentVerificationError,
PreconditionFailed,
RequestEntityTooLarge,