Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: query engine #231

Merged
merged 8 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
31 changes: 29 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@ description = "Limebit MedModels Crate"
[workspace.dependencies]
hashbrown = { version = "0.14.5", features = ["serde"] }
serde = { version = "1.0.203", features = ["derive"] }
ron = "0.8.1"
chrono = { version = "0.4.38", features = ["serde"] }
pyo3 = { version = "0.21.2", features = ["chrono"] }
polars = { version = "0.40.0", features = ["polars-io"] }
pyo3-polars = "0.14.0"
chrono = { version = "0.4.38", features = ["serde"] }

medmodels = { version = "0.1.2", path = "crates/medmodels" }
medmodels-core = { version = "0.1.2", path = "crates/medmodels-core" }
Expand Down
4 changes: 3 additions & 1 deletion crates/medmodels-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ medmodels-utils = { workspace = true }

polars = { workspace = true }
serde = { workspace = true }
ron = { workspace = true }
chrono = { workspace = true }
ron = "0.8.1"
roaring = "0.10.6"
itertools = "0.13.0"
3 changes: 3 additions & 0 deletions crates/medmodels-core/src/errors/medrecord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub enum MedRecordError {
ConversionError(String),
AssertionError(String),
SchemaError(String),
QueryError(String),
}

impl Error for MedRecordError {
Expand All @@ -20,6 +21,7 @@ impl Error for MedRecordError {
MedRecordError::ConversionError(message) => message,
MedRecordError::AssertionError(message) => message,
MedRecordError::SchemaError(message) => message,
MedRecordError::QueryError(message) => message,
}
}
}
Expand All @@ -32,6 +34,7 @@ impl Display for MedRecordError {
Self::ConversionError(message) => write!(f, "ConversionError: {}", message),
Self::AssertionError(message) => write!(f, "AssertionError: {}", message),
Self::SchemaError(message) => write!(f, "SchemaError: {}", message),
Self::QueryError(message) => write!(f, "QueryError: {}", message),
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/medmodels-core/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ impl From<GraphError> for MedRecordError {
}
}

pub type MedRecordResult<T> = Result<T, MedRecordError>;

#[cfg(test)]
mod test {
use super::{GraphError, MedRecordError};
Expand Down
223 changes: 211 additions & 12 deletions crates/medmodels-core/src/medrecord/datatypes/attribute.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
use super::{Contains, EndsWith, MedRecordValue, StartsWith};
use crate::errors::MedRecordError;
use super::{
Abs, Contains, EndsWith, Lowercase, MedRecordValue, Mod, Pow, Slice, StartsWith, Trim, TrimEnd,
TrimStart, Uppercase,
};
use crate::errors::{MedRecordError, MedRecordResult};
use medmodels_utils::implement_from_for_wrapper;
use serde::{Deserialize, Serialize};
use std::{cmp::Ordering, fmt::Display, hash::Hash};
use std::{
cmp::Ordering,
fmt::Display,
hash::Hash,
ops::{Add, Mul, Sub},
};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MedRecordAttribute {
Expand Down Expand Up @@ -43,15 +51,6 @@ impl TryFrom<MedRecordValue> for MedRecordAttribute {
}
}

impl Display for MedRecordAttribute {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::String(value) => write!(f, "{}", value),
Self::Int(value) => write!(f, "{}", value),
}
}
}

impl PartialEq for MedRecordAttribute {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
Expand Down Expand Up @@ -80,6 +79,140 @@ impl PartialOrd for MedRecordAttribute {
}
}

impl Display for MedRecordAttribute {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::String(value) => write!(f, "{}", value),
Self::Int(value) => write!(f, "{}", value),
}
}
}

// TODO: Add tests
impl Add for MedRecordAttribute {
type Output = MedRecordResult<Self>;

fn add(self, rhs: Self) -> Self::Output {
match (self, rhs) {
(MedRecordAttribute::String(value), MedRecordAttribute::String(rhs)) => {
Ok(MedRecordAttribute::String(value + rhs.as_str()))
}
(MedRecordAttribute::String(value), MedRecordAttribute::Int(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot add {} to {}", rhs, value)),
),
(MedRecordAttribute::Int(value), MedRecordAttribute::String(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot add {} to {}", rhs, value)),
),
(MedRecordAttribute::Int(value), MedRecordAttribute::Int(rhs)) => {
Ok(MedRecordAttribute::Int(value + rhs))
}
}
}
}

// TODO: Add tests
impl Sub for MedRecordAttribute {
type Output = MedRecordResult<Self>;

fn sub(self, rhs: Self) -> Self::Output {
match (self, rhs) {
(MedRecordAttribute::String(value), MedRecordAttribute::String(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot subtract {} from {}", rhs, value)),
),
(MedRecordAttribute::String(value), MedRecordAttribute::Int(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot subtract {} from {}", rhs, value)),
),
(MedRecordAttribute::Int(value), MedRecordAttribute::String(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot subtract {} from {}", rhs, value)),
),
(MedRecordAttribute::Int(value), MedRecordAttribute::Int(rhs)) => {
Ok(MedRecordAttribute::Int(value - rhs))
}
}
}
}

// TODO: Add tests
impl Mul for MedRecordAttribute {
type Output = MedRecordResult<Self>;

fn mul(self, rhs: Self) -> Self::Output {
match (self, rhs) {
(MedRecordAttribute::String(value), MedRecordAttribute::String(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot multiply {} by {}", value, rhs)),
),
(MedRecordAttribute::String(value), MedRecordAttribute::Int(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot multiply {} by {}", value, rhs)),
),
(MedRecordAttribute::Int(value), MedRecordAttribute::String(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot multiply {} by {}", value, rhs)),
),
(MedRecordAttribute::Int(value), MedRecordAttribute::Int(rhs)) => {
Ok(MedRecordAttribute::Int(value * rhs))
}
}
}
}

// TODO: Add tests
impl Pow for MedRecordAttribute {
fn pow(self, rhs: Self) -> MedRecordResult<Self> {
match (self, rhs) {
(MedRecordAttribute::String(value), MedRecordAttribute::String(rhs)) => {
Err(MedRecordError::AssertionError(format!(
"Cannot raise {} to the power of {}",
value, rhs
)))
}
(MedRecordAttribute::String(value), MedRecordAttribute::Int(rhs)) => {
Err(MedRecordError::AssertionError(format!(
"Cannot raise {} to the power of {}",
value, rhs
)))
}
(MedRecordAttribute::Int(value), MedRecordAttribute::String(rhs)) => {
Err(MedRecordError::AssertionError(format!(
"Cannot raise {} to the power of {}",
value, rhs
)))
}
(MedRecordAttribute::Int(value), MedRecordAttribute::Int(rhs)) => {
Ok(MedRecordAttribute::Int(value.pow(rhs as u32)))
}
}
}
}

// TODO: Add tests
impl Mod for MedRecordAttribute {
fn r#mod(self, rhs: Self) -> MedRecordResult<Self> {
match (self, rhs) {
(MedRecordAttribute::String(value), MedRecordAttribute::String(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot mod {} by {}", value, rhs)),
),
(MedRecordAttribute::String(value), MedRecordAttribute::Int(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot mod {} by {}", value, rhs)),
),
(MedRecordAttribute::Int(value), MedRecordAttribute::String(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot mod {} by {}", value, rhs)),
),
(MedRecordAttribute::Int(value), MedRecordAttribute::Int(rhs)) => {
Ok(MedRecordAttribute::Int(value % rhs))
}
}
}
}

// TODO: Add tests
impl Abs for MedRecordAttribute {
fn abs(self) -> Self {
match self {
MedRecordAttribute::Int(value) => MedRecordAttribute::Int(value.abs()),
_ => self,
}
}
}

impl StartsWith for MedRecordAttribute {
fn starts_with(&self, other: &Self) -> bool {
match (self, other) {
Expand Down Expand Up @@ -137,6 +270,72 @@ impl Contains for MedRecordAttribute {
}
}

// TODO: Add tests
impl Slice for MedRecordAttribute {
fn slice(self, range: std::ops::Range<usize>) -> Self {
match self {
MedRecordAttribute::String(value) => value[range].into(),
MedRecordAttribute::Int(value) => value.to_string()[range].into(),
}
}
}

// TODO: Add tests
impl Trim for MedRecordAttribute {
fn trim(self) -> Self {
match self {
MedRecordAttribute::String(value) => {
MedRecordAttribute::String(value.trim().to_string())
}
_ => self,
}
}
}

// TODO: Add tests
impl TrimStart for MedRecordAttribute {
fn trim_start(self) -> Self {
match self {
MedRecordAttribute::String(value) => {
MedRecordAttribute::String(value.trim_start().to_string())
}
_ => self,
}
}
}

// TODO: Add tests
impl TrimEnd for MedRecordAttribute {
fn trim_end(self) -> Self {
match self {
MedRecordAttribute::String(value) => {
MedRecordAttribute::String(value.trim_end().to_string())
}
_ => self,
}
}
}

// TODO: Add tests
impl Lowercase for MedRecordAttribute {
fn lowercase(self) -> Self {
match self {
MedRecordAttribute::String(value) => MedRecordAttribute::String(value.to_lowercase()),
_ => self,
}
}
}

// TODO: Add tests
impl Uppercase for MedRecordAttribute {
fn uppercase(self) -> Self {
match self {
MedRecordAttribute::String(value) => MedRecordAttribute::String(value.to_uppercase()),
_ => self,
}
}
}

#[cfg(test)]
mod test {
use super::MedRecordAttribute;
Expand Down
Loading