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

feat(torii-grpc): IN operator for comparison #2812

Merged
merged 4 commits into from
Dec 17, 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
7 changes: 7 additions & 0 deletions crates/torii/grpc/proto/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,14 @@ message MemberValue {
oneof value_type {
Primitive primitive = 1;
string string = 2;
MemberValueList list = 3;
}
}

message MemberValueList {
repeated MemberValue values = 1;
}

message MemberClause {
string model = 2;
string member = 3;
Expand Down Expand Up @@ -152,6 +157,8 @@ enum ComparisonOperator {
GTE = 3;
LT = 4;
LTE = 5;
IN = 6;
NOT_IN = 7;
}

message Token {
Expand Down
99 changes: 72 additions & 27 deletions crates/torii/grpc/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -773,15 +773,32 @@
let comparison_operator = ComparisonOperator::from_repr(member_clause.operator as usize)
.expect("invalid comparison operator");

let comparison_value =
match member_clause.value.ok_or(QueryError::MissingParam("value".into()))?.value_type {
Some(ValueType::String(value)) => value,
fn prepare_comparison(
value: &proto::types::MemberValue,
bind_values: &mut Vec<String>,
) -> Result<String, Error> {
match &value.value_type {
Some(ValueType::String(value)) => {
bind_values.push(value.to_string());
Ok("?".to_string())

Check warning on line 783 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L776-L783

Added lines #L776 - L783 were not covered by tests
}
Some(ValueType::Primitive(value)) => {
let primitive: Primitive = value.try_into()?;
primitive.to_sql_value()
let primitive: Primitive = (value.clone()).try_into()?;
bind_values.push(primitive.to_sql_value());
Ok("?".to_string())

Check warning on line 788 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L786-L788

Added lines #L786 - L788 were not covered by tests
}
None => return Err(QueryError::MissingParam("value_type".into()).into()),
};
Some(ValueType::List(values)) => Ok(format!(
"({})",
values
.values
.iter()
.map(|v| prepare_comparison(v, bind_values))
.collect::<Result<Vec<String>, Error>>()?
.join(", ")

Check warning on line 797 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L790-L797

Added lines #L790 - L797 were not covered by tests
)),
None => Err(QueryError::MissingParam("value_type".into()).into()),

Check warning on line 799 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L799

Added line #L799 was not covered by tests
}
}

Check warning on line 801 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L801

Added line #L801 was not covered by tests

let (namespace, model) = member_clause
.model
Expand Down Expand Up @@ -822,8 +839,15 @@
self.model_cache.models(&model_ids).await?.into_iter().map(|m| m.schema).collect();

// Use the member name directly as the column name since it's already flattened
let mut where_clause =
format!("[{}].[{}] {comparison_operator} ?", member_clause.model, member_clause.member);
let mut bind_values = Vec::new();
let value = prepare_comparison(
&member_clause.value.clone().ok_or(QueryError::MissingParam("value".into()))?,
&mut bind_values,
)?;
let mut where_clause = format!(
"[{}].[{}] {comparison_operator} {value}",
member_clause.model, member_clause.member
);

Check warning on line 850 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L842-L850

Added lines #L842 - L850 were not covered by tests
if entity_updated_after.is_some() {
where_clause += &format!(" AND {table}.updated_at >= ?");
}
Expand All @@ -837,15 +861,19 @@
limit,
offset,
)?;
let mut count_query = sqlx::query_scalar(&count_query);
for value in &bind_values {
count_query = count_query.bind(value);
}
if let Some(entity_updated_after) = entity_updated_after.clone() {
count_query = count_query.bind(entity_updated_after);
}
let total_count = count_query.fetch_optional(&self.pool).await?.unwrap_or(0);

Check warning on line 871 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L864-L871

Added lines #L864 - L871 were not covered by tests

let total_count = sqlx::query_scalar(&count_query)
.bind(comparison_value.clone())
.bind(entity_updated_after.clone())
.fetch_optional(&self.pool)
.await?
.unwrap_or(0);

let mut query = sqlx::query(&entity_query).bind(comparison_value);
let mut query = sqlx::query(&entity_query);
for value in &bind_values {
query = query.bind(value);
}

Check warning on line 876 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L873-L876

Added lines #L873 - L876 were not covered by tests
if let Some(entity_updated_after) = entity_updated_after.clone() {
query = query.bind(entity_updated_after);
}
Expand Down Expand Up @@ -1356,17 +1384,34 @@
ClauseType::Member(member) => {
let comparison_operator = ComparisonOperator::from_repr(member.operator as usize)
.expect("invalid comparison operator");
let value = member.value.clone();
let comparison_value =
match value.ok_or(QueryError::MissingParam("value".into()))?.value_type {
Some(ValueType::String(value)) => value,
let value = member.value.clone().ok_or(QueryError::MissingParam("value".into()))?;
fn prepare_comparison(
value: &proto::types::MemberValue,
bind_values: &mut Vec<String>,
) -> Result<String, Error> {
match &value.value_type {
Some(ValueType::String(value)) => {
bind_values.push(value.to_string());
Ok("?".to_string())

Check warning on line 1395 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L1387-L1395

Added lines #L1387 - L1395 were not covered by tests
}
Some(ValueType::Primitive(value)) => {
let primitive: Primitive = value.try_into()?;
primitive.to_sql_value()
let primitive: Primitive = (value.clone()).try_into()?;
bind_values.push(primitive.to_sql_value());
Ok("?".to_string())

Check warning on line 1400 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L1398-L1400

Added lines #L1398 - L1400 were not covered by tests
}
None => return Err(QueryError::MissingParam("value_type".into()).into()),
};
bind_values.push(comparison_value);
Some(ValueType::List(values)) => Ok(format!(
"({})",
values
.values
.iter()
.map(|v| prepare_comparison(v, bind_values))
.collect::<Result<Vec<String>, Error>>()?
.join(", ")

Check warning on line 1409 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L1402-L1409

Added lines #L1402 - L1409 were not covered by tests
)),
None => Err(QueryError::MissingParam("value_type".into()).into()),

Check warning on line 1411 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L1411

Added line #L1411 was not covered by tests
}
}
let value = prepare_comparison(&value, &mut bind_values)?;

Check warning on line 1414 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L1413-L1414

Added lines #L1413 - L1414 were not covered by tests

let model = member.model.clone();
// Get or create unique alias for this model
Expand Down Expand Up @@ -1394,7 +1439,7 @@

// Use the column name directly since it's already flattened
where_clauses
.push(format!("([{alias}].[{}] {comparison_operator} ?)", member.member));
.push(format!("([{alias}].[{}] {comparison_operator} {value})", member.member));

Check warning on line 1442 in crates/torii/grpc/src/server/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/server/mod.rs#L1442

Added line #L1442 was not covered by tests
}
ClauseType::Composite(nested) => {
// Handle nested composite by recursively building the clause
Expand Down
6 changes: 6 additions & 0 deletions crates/torii/grpc/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@
Gte,
Lt,
Lte,
In,
NotIn,
}

impl fmt::Display for ComparisonOperator {
Expand All @@ -198,6 +200,8 @@
ComparisonOperator::Lte => write!(f, "<="),
ComparisonOperator::Neq => write!(f, "!="),
ComparisonOperator::Eq => write!(f, "="),
ComparisonOperator::In => write!(f, "IN"),
ComparisonOperator::NotIn => write!(f, "NOT IN"),

Check warning on line 204 in crates/torii/grpc/src/types/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/types/mod.rs#L203-L204

Added lines #L203 - L204 were not covered by tests
}
}
}
Expand All @@ -211,6 +215,8 @@
proto::types::ComparisonOperator::Lt => ComparisonOperator::Lt,
proto::types::ComparisonOperator::Lte => ComparisonOperator::Lte,
proto::types::ComparisonOperator::Neq => ComparisonOperator::Neq,
proto::types::ComparisonOperator::In => ComparisonOperator::In,
proto::types::ComparisonOperator::NotIn => ComparisonOperator::NotIn,

Check warning on line 219 in crates/torii/grpc/src/types/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/grpc/src/types/mod.rs#L218-L219

Added lines #L218 - L219 were not covered by tests
}
}
}
Expand Down
Loading