Skip to content
37 changes: 12 additions & 25 deletions src/services/core/tx.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::classes::OperationDomain;
use crate::services::core::classes::Ref;
use crate::services::event::{Class, Event, HasId, QueryClass};
use crate::services::event::{Class, Event, HasId};
use crate::services::transactor::tx::Doc;
use derive_builder::Builder;
use serde::{Deserialize, Deserializer, Serialize};
Expand Down Expand Up @@ -85,12 +85,9 @@ impl<T> HasId for TxWorkspaceEvent<T> {
}
}

impl<T: Class> Event for TxWorkspaceEvent<T> {
impl<T: Debug> Event for TxWorkspaceEvent<T> {
fn matches(value: &Value) -> bool {
if value.get("_class").and_then(|v| v.as_str()) != Some(Self::CLASS) {
return false;
}
value.get("objectClass").and_then(|v| v.as_str()) == Some(T::CLASS)
value.get("_class").and_then(|v| v.as_str()) == Some(Self::CLASS)
}
}

Expand All @@ -107,12 +104,9 @@ impl<T: Debug> Class for TxDomainEvent<T> {
const CLASS: &'static str = crate::services::core::class::TxDomainEvent;
}

impl<T: QueryClass + Class> Event for TxDomainEvent<T> {
impl<T: Debug> Event for TxDomainEvent<T> {
fn matches(value: &Value) -> bool {
if value.get("_class").and_then(|v| v.as_str()) != Some(Self::CLASS) {
return false;
}
value.get("objectClass").and_then(|v| v.as_str()) == Some(T::CLASS)
value.get("_class").and_then(|v| v.as_str()) == Some(Self::CLASS)
}
}

Expand Down Expand Up @@ -224,36 +218,29 @@ impl<C: Class> Event for TxUpdateDoc<C> {

#[derive(Clone, Debug, Serialize, Deserialize, Builder)]
#[serde(rename_all = "camelCase")]
pub struct TxRemoveDoc<C> {
pub struct TxRemoveDoc {
#[serde(flatten)]
pub txcud: TxCUD,

#[serde(skip)]
#[builder(setter(skip), default)]
pub(crate) _phantom: PhantomData<C>,
}

impl<C: Clone> TxRemoveDoc<C> {
pub fn builder() -> TxRemoveDocBuilder<C> {
impl TxRemoveDoc {
pub fn builder() -> TxRemoveDocBuilder {
TxRemoveDocBuilder::default()
}
}

impl<C: Debug> Class for TxRemoveDoc<C> {
impl Class for TxRemoveDoc {
const CLASS: &'static str = crate::services::core::class::TxRemoveDoc;
}

impl<C> HasId for TxRemoveDoc<C> {
impl HasId for TxRemoveDoc {
fn id(&self) -> &str {
&self.txcud.object_id
}
}

impl<C: Class> Event for TxRemoveDoc<C> {
impl Event for TxRemoveDoc {
fn matches(value: &Value) -> bool {
if value.get("_class").and_then(|v| v.as_str()) != Some(Self::CLASS) {
return false;
}
value.get("objectClass").and_then(|v| v.as_str()) == Some(C::CLASS)
value.get("_class").and_then(|v| v.as_str()) == Some(Self::CLASS)
}
}
15 changes: 8 additions & 7 deletions src/services/transactor/backend/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,16 @@ impl HttpBackend {
params: impl IntoIterator<Item = (String, Value)>,
) -> Result<T> {
let mut url = self.base().join(path)?;
let mut qp = url.query_pairs_mut();
for (name, value) in params {
if let Value::String(string) = &value {
qp.append_pair(&name, string);
} else {
qp.append_pair(&name, &value.to_string());
{
let mut qp = url.query_pairs_mut();
for (name, value) in params {
if let Value::String(string) = &value {
qp.append_pair(&name, string);
} else {
qp.append_pair(&name, &value.to_string());
}
}
}
Comment thread
n1kolasM marked this conversation as resolved.
drop(qp);

<crate::services::HttpClient as JsonClient>::get(&self.inner.client, self, url).await
}
Expand Down
2 changes: 1 addition & 1 deletion src/services/transactor/comm/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub type MessageExtra = HashMap<String, json::Value>;
#[serde(rename_all = "lowercase")]
pub enum MessageType {
#[default]
Message,
Text,
Activity,
}

Expand Down
52 changes: 28 additions & 24 deletions src/services/transactor/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use derive_builder::Builder;
use serde::{Deserialize, Serialize, de::DeserializeOwned};
use serde_json::{self as json, Value};
use std::collections::HashMap;
use std::marker::PhantomData;
use std::sync::LazyLock;
use std::sync::atomic::AtomicUsize;

Expand All @@ -30,7 +29,6 @@ use crate::services::core::classes::{Ref, Timestamp};
use crate::services::core::ser::Data;
use crate::services::core::tx::{Tx, TxCUD, TxCreateDoc, TxRemoveDoc};
use crate::services::core::{Account, FindResult, PersonId};
use crate::services::event::Class;
use crate::services::transactor::backend::Backend;
use crate::services::transactor::methods::Method;
use crate::{Error, Result};
Expand All @@ -55,10 +53,13 @@ pub(crate) fn generate_object_id() -> Ref {
}

#[derive(Default, Debug, derive_builder::Builder, Clone)]
pub struct CreateDocument<C> {
pub struct CreateDocument<C: Serialize> {
Comment thread
n1kolasM marked this conversation as resolved.
#[builder(setter(into), default = generate_object_id())]
object_id: Ref,

#[builder(setter(into))]
object_class: String,

#[builder(setter(into), default = Utc::now())]
modified_on: Timestamp,

Expand All @@ -77,13 +78,13 @@ pub struct CreateDocument<C> {
attributes: C,
}

impl<C: Clone> CreateDocument<C> {
impl<C: Clone + Serialize> CreateDocument<C> {
pub fn builder() -> CreateDocumentBuilder<C> {
CreateDocumentBuilder::default()
}
}

impl<C: Class + Serialize> Transaction for CreateDocument<C> {
impl<C: Serialize> Transaction for CreateDocument<C> {
fn to_value(self) -> Result<Value> {
let doc = TxCreateDoc {
txcud: TxCUD {
Expand All @@ -103,7 +104,7 @@ impl<C: Class + Serialize> Transaction for CreateDocument<C> {
object_space: self.object_space,
},
object_id: self.object_id,
object_class: C::CLASS.into(),
object_class: self.object_class,
attached_to: None,
attached_to_class: None,
collection: None,
Expand All @@ -117,10 +118,13 @@ impl<C: Class + Serialize> Transaction for CreateDocument<C> {
}

#[derive(Default, Debug, derive_builder::Builder, Clone, Serialize, Deserialize)]
pub struct RemoveDocument<C> {
pub struct RemoveDocument {
#[builder(setter(into))]
object_id: Ref,

#[builder(setter(into))]
object_class: String,

#[builder(setter(into), default)]
modified_on: Option<Timestamp>,

Expand All @@ -135,21 +139,17 @@ pub struct RemoveDocument<C> {

#[builder(setter(into))]
object_space: String,

#[serde(skip)]
#[builder(setter(skip), default)]
_phantom: PhantomData<C>,
}

impl<C: Clone> RemoveDocument<C> {
pub fn builder() -> RemoveDocumentBuilder<C> {
impl RemoveDocument {
pub fn builder() -> RemoveDocumentBuilder {
RemoveDocumentBuilder::default()
}
}

impl<C: Class> Transaction for RemoveDocument<C> {
impl Transaction for RemoveDocument {
fn to_value(self) -> Result<Value> {
let doc = TxRemoveDoc::<C> {
let doc = TxRemoveDoc {
txcud: TxCUD {
tx: Tx {
doc: Doc {
Expand All @@ -167,12 +167,11 @@ impl<C: Class> Transaction for RemoveDocument<C> {
object_space: self.object_space,
},
object_id: self.object_id,
object_class: C::CLASS.into(),
object_class: self.object_class,
attached_to: None,
attached_to_class: None,
collection: None,
},
_phantom: Default::default(),
};

Ok(json::to_value(&doc)?)
Expand Down Expand Up @@ -319,14 +318,16 @@ impl FindOptionsBuilder {
pub trait DocumentClient {
fn get_account(&self) -> impl Future<Output = Result<Account>>;

fn find_all<C: Class + DeserializeOwned, Q: Serialize>(
fn find_all<Q: Serialize, C: DeserializeOwned>(
&self,
class: &str,
query: Q,
options: &FindOptions,
) -> impl Future<Output = Result<FindResult<C>>>;

fn find_one<C: Class + DeserializeOwned, Q: Serialize>(
fn find_one<Q: Serialize, C: DeserializeOwned>(
&self,
class: &str,
query: Q,
options: &FindOptions,
) -> impl Future<Output = Result<Option<C>>>;
Expand All @@ -337,8 +338,9 @@ impl<B: Backend> DocumentClient for super::TransactorClient<B> {
self.get(Method::Account, []).await
}

async fn find_all<C: Class + DeserializeOwned, Q: Serialize>(
async fn find_all<Q: Serialize, C: DeserializeOwned>(
&self,
class: &str,
query: Q,
options: &FindOptions,
) -> Result<FindResult<C>> {
Expand All @@ -354,7 +356,7 @@ impl<B: Backend> DocumentClient for super::TransactorClient<B> {
.get(
Method::FindAll,
[
(String::from("class"), C::CLASS.into()),
(String::from("class"), class.into()),
(String::from("query"), json::to_value(query)?),
(String::from("options"), json::to_value(options)?),
],
Expand Down Expand Up @@ -387,7 +389,7 @@ impl<B: Backend> DocumentClient for super::TransactorClient<B> {
for entry in result.value.iter_mut() {
let object = entry.as_object_mut().unwrap();
if !object.contains_key("_class") {
object.insert("_class".into(), Value::String(C::CLASS.into()));
object.insert("_class".into(), Value::String(class.into()));
}

for (k, v) in query.iter() {
Expand Down Expand Up @@ -427,13 +429,15 @@ impl<B: Backend> DocumentClient for super::TransactorClient<B> {
Ok(result)
}

async fn find_one<C: Class + DeserializeOwned, Q: Serialize>(
async fn find_one<Q: Serialize, C: DeserializeOwned>(
&self,
class: &str,
query: Q,
options: &FindOptions,
) -> Result<Option<C>> {
Ok(self
.find_all::<C, _>(
.find_all::<_, C>(
class,
query,
&FindOptions {
limit: Some(1),
Expand Down
3 changes: 2 additions & 1 deletion src/services/transactor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ impl<B: Backend> TransactorClient<B> {
}

pub async fn remove<T: DocT + Clone>(&self, doc: &T) -> Result<()> {
let tx = RemoveDocument::<T>::builder()
let tx = RemoveDocument::builder()
.object_class(&doc.doc().obj.class)
.object_id(doc.id())
.object_space(&doc.doc().space)
.build()
Expand Down
17 changes: 9 additions & 8 deletions src/services/transactor/subscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl<C: Class> SubscribedQuery<C> {
pub enum TxEvent<C> {
Created(Box<TxCreateDoc<C>>),
Updated(Box<TxUpdateDoc<C>>),
Deleted(Box<TxRemoveDoc<C>>),
Deleted(Box<TxRemoveDoc>),
}

impl<T> TxEvent<WithLookup<T>> {
Expand All @@ -53,10 +53,7 @@ impl<T> TxEvent<WithLookup<T>> {
retrieve: tx.retrieve,
_phantom: Default::default(),
})),
TxEvent::Deleted(tx) => TxEvent::Deleted(Box::new(TxRemoveDoc {
txcud: tx.txcud,
_phantom: Default::default(),
})),
TxEvent::Deleted(tx) => TxEvent::Deleted(Box::new(TxRemoveDoc { txcud: tx.txcud })),
}
}
}
Expand All @@ -74,8 +71,10 @@ impl<C: Class + DeserializeOwned + Send + Unpin + 'static> Stream for Subscribed
} else if TxUpdateDoc::<C>::matches(&value) {
let tx: TxUpdateDoc<C> = serde_json::from_value(value)?;
return Poll::Ready(Some(Ok(TxEvent::Updated(Box::new(tx)))));
} else if TxRemoveDoc::<C>::matches(&value) {
let tx: TxRemoveDoc<C> = serde_json::from_value(value)?;
} else if TxRemoveDoc::matches(&value)
&& value.get("objectClass").and_then(|v| v.as_str()) == Some(C::CLASS)
{
Comment thread
n1kolasM marked this conversation as resolved.
let tx: TxRemoveDoc = serde_json::from_value(value)?;
return Poll::Ready(Some(Ok(TxEvent::Deleted(Box::new(tx)))));
}

Expand Down Expand Up @@ -120,7 +119,9 @@ pub(super) fn live_query<
) -> impl Stream<Item = Result<LiveQueryEvent<C>>> + Send {
let client_clone = client.clone();
let initial_fetch = async move {
let results = client_clone.find_all::<C, Q>(query, &options).await?;
let results = client_clone
.find_all::<Q, C>(C::CLASS, query, &options)
.await?;
Ok(LiveQueryEvent::Initial(results.value))
};

Expand Down