Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ mod precondition;
pub mod request_options;

use crate::{
client::client_request::ReadEventTypeRequest,
error::ClientError,
event::{Event, EventCandidate, ManagementEvent},
request_options::EventType,
};
use client_request::{
ClientRequest, ListEventTypesRequest, ListSubjectsRequest, ObserveEventsRequest,
OneShotRequest, PingRequest, ReadEventsRequest, RegisterEventSchemaRequest,
RunEventqlQueryRequest, StreamingRequest, VerifyApiTokenRequest, WriteEventsRequest,
list_event_types::EventType,
};
use futures::Stream;
pub use precondition::Precondition;
Expand Down Expand Up @@ -211,6 +212,49 @@ impl Client {
Ok(response)
}

/// Reads a specific event type from the DB instance.
///
/// ```
/// use eventsourcingdb::event::EventCandidate;
/// use futures::StreamExt;
/// # use serde_json::json;
/// # tokio_test::block_on(async {
/// # let container = eventsourcingdb::container::Container::start_preview().await.unwrap();
/// let db_url = "http://localhost:3000/";
/// let api_token = "secrettoken";
/// # let db_url = container.get_base_url().await.unwrap();
/// # let api_token = container.get_api_token();
/// let client = eventsourcingdb::client::Client::new(db_url, api_token);
/// let event_type = "io.eventsourcingdb.test";
/// let schema = json!({
/// "type": "object",
/// "properties": {
/// "id": {
/// "type": "string"
/// },
/// "name": {
/// "type": "string"
/// }
/// },
/// "required": ["id", "name"]
/// });
/// client.register_event_schema(event_type, &schema).await.expect("Failed to register event types");
/// let type_info = client.read_event_type(event_type).await.expect("Failed to read event type");
/// println!("Found Type {} with schema {:?}", type_info.name, type_info.schema);
/// # })
/// ```
///
/// # Errors
/// This function will return an error if the request fails or if the URL is invalid.
pub async fn read_event_type(&self, event_type: &str) -> Result<EventType, ClientError> {
let response = self
.request_oneshot(ReadEventTypeRequest {
event_type: event_type.to_string(),
})
.await?;
Ok(response)
}

/// Observe events from the DB instance.
///
/// ```
Expand Down
2 changes: 2 additions & 0 deletions src/client/client_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod list_event_types;
mod list_subjects;
mod observe_events;
mod ping;
mod read_event_type;
mod read_events;
mod register_event_schema;
mod run_eventql_query;
Expand All @@ -14,6 +15,7 @@ pub use list_event_types::ListEventTypesRequest;
pub use list_subjects::ListSubjectsRequest;
pub use observe_events::ObserveEventsRequest;
pub use ping::PingRequest;
pub use read_event_type::ReadEventTypeRequest;
pub use read_events::ReadEventsRequest;
pub use register_event_schema::RegisterEventSchemaRequest;
pub use run_eventql_query::RunEventqlQueryRequest;
Expand Down
16 changes: 3 additions & 13 deletions src/client/client_request/list_event_types.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
use super::{ClientRequest, StreamingRequest};
use reqwest::Method;
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::error::ClientError;
use serde::Serialize;

use super::{ClientRequest, StreamingRequest};
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct EventType {
#[serde(rename = "eventType")]
pub name: String,
pub is_phantom: bool,
pub schema: Option<Value>,
}
use crate::{client::request_options::EventType, error::ClientError};

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
Expand Down
28 changes: 28 additions & 0 deletions src/client/client_request/read_event_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use reqwest::Method;
use serde::Serialize;

use crate::{
client::client_request::{ClientRequest, OneShotRequest},
error::ClientError,
request_options::EventType,
};

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ReadEventTypeRequest {
#[serde(rename = "eventType")]
/// The name of the event type to read
pub event_type: String,
}

impl ClientRequest for ReadEventTypeRequest {
const URL_PATH: &'static str = "/api/v1/read-event-type";
const METHOD: Method = Method::POST;

fn body(&self) -> Option<Result<impl Serialize, ClientError>> {
Some(Ok(self))
}
}
impl OneShotRequest for ReadEventTypeRequest {
type Response = EventType;
}
16 changes: 15 additions & 1 deletion src/client/request_options.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! This module contains supporting options for the client requests.

use serde::Serialize;
use serde::{Deserialize, Serialize};
use serde_json::Value;

/// Options for reading events from the database
#[derive(Debug, Default, Clone, Serialize)]
Expand Down Expand Up @@ -112,3 +113,16 @@ pub struct ObserveFromLatestEventOptions<'a> {
#[serde(rename = "type")]
pub ty: &'a str,
}

/// Represents an event type in the database
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct EventType {
/// The name of the event type
#[serde(rename = "eventType")]
pub name: String,
/// Whether the event type is a phantom type
pub is_phantom: bool,
/// The schema of the event type, if available
pub schema: Option<Value>,
}
13 changes: 12 additions & 1 deletion src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,25 @@ impl Container {
/// Shortcut method to start the container with default settings.
///
/// This is the same as calling [`Container::builder`] and then [`ContainerBuilder::start`].
/// In most cases this will create a contaienr with the latest image tag and a working configuration.
/// In most cases this will create a container with the latest image tag and a working configuration.
///
/// # Errors
/// This functions returns the errors of [`ContainerBuilder::start()`]
pub async fn start_default() -> Result<Container, ContainerError> {
Self::builder().start().await
}

/// Shortcut method to start the container with the preview tag and default settings.
///
/// This is the same as calling [`Container::builder`], [`Container::with_image_tag("preview")`] and then [`ContainerBuilder::start`].
/// In most cases this will create a container with the latest image tag and a working configuration.
///
/// # Errors
/// This functions returns the errors of [`ContainerBuilder::start()`]
pub async fn start_preview() -> Result<Container, ContainerError> {
Self::builder().with_image_tag("preview").start().await
}

/// Get the host of the container.
///
/// This is the host that you can use to connect to the database. In most cases this will be `localhost`.
Expand Down