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): enum support #874

Merged
merged 9 commits into from
Sep 8, 2023
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
23 changes: 16 additions & 7 deletions crates/dojo-lang/src/manifest_test_data/manifest
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ test_manifest_file
}
],
"outputs": [],
"class_hash": "0x3459b99fd17b3bf9aeb6c55b610a457520785646f5c80c21d07041403a25315",
"class_hash": "0x205287b11aa6c42e3cef3539607aa250c2b9ffe27f847af8e88f005e1b3525d",
"dependencies": [],
"abi": [
{
Expand Down Expand Up @@ -701,11 +701,11 @@ test_manifest_file
},
{
"name": "direction",
"type": "dojo_examples::systems::move::Direction"
"type": "dojo_examples::components::Direction"
}
],
"outputs": [],
"class_hash": "0x578416d298f2f6c280a229f58fd7b5b2486285700fcfde9ad102c4052d3804e",
"class_hash": "0x501dbe28cf4e7f3a47c9abeee23c85992b97fdaa324c1fcb1e2a638882fc470",
"dependencies": [],
"abi": [
{
Expand All @@ -721,8 +721,12 @@ test_manifest_file
},
{
"type": "enum",
"name": "dojo_examples::systems::move::Direction",
"name": "dojo_examples::components::Direction",
"variants": [
{
"name": "None",
"type": "()"
},
{
"name": "Left",
"type": "()"
Expand Down Expand Up @@ -779,7 +783,7 @@ test_manifest_file
"inputs": [
{
"name": "direction",
"type": "dojo_examples::systems::move::Direction"
"type": "dojo_examples::components::Direction"
},
{
"name": "ctx",
Expand All @@ -801,7 +805,7 @@ test_manifest_file
},
{
"name": "direction",
"type": "dojo_examples::systems::move::Direction",
"type": "dojo_examples::components::Direction",
"kind": "data"
}
]
Expand Down Expand Up @@ -952,9 +956,14 @@ test_manifest_file
"name": "remaining",
"type": "u8",
"key": false
},
{
"name": "last_direction",
"type": "Direction",
"key": false
}
],
"class_hash": "0x74c8a6b2e93b4a34788c23eb3d931da62d5a973ef66ba0a671de41b1607a9a4",
"class_hash": "0x451a367ced4c22bfc661e6a342391faa6087d3162ea53cf4c6cc86c8630de49",
"abi": [
{
"type": "function",
Expand Down
6 changes: 3 additions & 3 deletions crates/torii/client/src/contract/system_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async fn test_system() {
let component = world.component("Moves", block_id).await.unwrap();
let moves = component.entity(vec![account.address()], block_id).await.unwrap();

assert_eq!(moves, vec![10_u8.into()]);
assert_eq!(moves, vec![10_u8.into(), FieldElement::ZERO]);

let move_system = world.system("move", block_id).await.unwrap();

Expand All @@ -48,11 +48,11 @@ async fn test_system() {

let moves = component.entity(vec![account.address()], block_id).await.unwrap();

assert_eq!(moves, vec![8_u8.into()]);
assert_eq!(moves, vec![8_u8.into(), FieldElement::THREE]);

let position_component = world.component("Position", block_id).await.unwrap();

let position = position_component.entity(vec![account.address()], block_id).await.unwrap();

assert_eq!(position, vec![11_u8.into(), 11_u8.into()]);
assert_eq!(position, vec![9_u8.into(), 9_u8.into()]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm why did this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a None state to the Direction enum so it shifted the cmds up by one

}
87 changes: 54 additions & 33 deletions crates/torii/core/src/sql.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use anyhow::Result;
use async_trait::async_trait;
use chrono::{DateTime, Utc};
Expand Down Expand Up @@ -27,6 +29,7 @@ pub struct Sql {
world_address: FieldElement,
pool: Pool<Sqlite>,
query_queue: Mutex<Vec<String>>,
sql_types: Mutex<HashMap<String, &'static str>>,
}

impl Sql {
Expand All @@ -50,7 +53,29 @@ impl Sql {

tx.commit().await?;

Ok(Self { pool, world_address, query_queue: Mutex::new(vec![]) })
let sql_types = HashMap::from([
("u8".to_string(), "INTEGER"),
("u16".to_string(), "INTEGER"),
("u32".to_string(), "INTEGER"),
("u64".to_string(), "INTEGER"),
("u128".to_string(), "TEXT"),
("u256".to_string(), "TEXT"),
("usize".to_string(), "INTEGER"),
("bool".to_string(), "INTEGER"),
("Cursor".to_string(), "TEXT"),
("ContractAddress".to_string(), "TEXT"),
("ClassHash".to_string(), "TEXT"),
("DateTime".to_string(), "TEXT"),
("felt252".to_string(), "TEXT"),
("Enum".to_string(), "INTEGER"),
]);

Ok(Self {
pool,
world_address,
query_queue: Mutex::new(vec![]),
sql_types: Mutex::new(sql_types),
})
}
}

Expand Down Expand Up @@ -157,6 +182,8 @@ impl State for Sql {
}

async fn register_component(&self, component: Component) -> Result<()> {
let mut sql_types = self.sql_types.lock().await;

let component_id = component.name.to_lowercase();
let mut queries = vec![format!(
"INSERT INTO components (id, name, class_hash) VALUES ('{}', '{}', '{:#x}') ON \
Expand All @@ -169,12 +196,24 @@ impl State for Sql {
component.name.to_lowercase()
);

for member in component.clone().members {
component_table_query.push_str(&format!(
"external_{} {}, ",
member.name,
sql_type(&member.ty)?
for member in &component.members {
// FIXME: defaults all unknown component types to Enum for now until we support nested
// components
let (sql_type, member_type) = match sql_types.get(&member.ty) {
Some(sql_type) => (*sql_type, member.ty.as_str()),
None => {
sql_types.insert(member.ty.clone(), "INTEGER");
("INTEGER", "Enum")
}
};

queries.push(format!(
"INSERT OR IGNORE INTO component_members (component_id, name, type, key) VALUES \
('{}', '{}', '{}', {})",
component_id, member.name, member_type, member.key,
));

component_table_query.push_str(&format!("external_{} {}, ", member.name, sql_type));
}

component_table_query.push_str(
Expand All @@ -183,15 +222,8 @@ impl State for Sql {
);
queries.push(component_table_query);

for member in component.members {
queries.push(format!(
"INSERT OR IGNORE INTO component_members (component_id, name, type, key) VALUES \
('{}', '{}', '{}', {})",
component_id, member.name, member.ty, member.key,
));
}

self.queue(queries).await;

// Since previous query has not been executed, we have to make sure created_at exists
let created_at: DateTime<Utc> =
match sqlx::query("SELECT created_at FROM components WHERE id = ?")
Expand Down Expand Up @@ -259,7 +291,9 @@ impl State for Sql {
member_values.extend(keys);
member_values.extend(values);

let (names_str, values_str) = format_values(member_names_result, member_values)?;
let sql_types = self.sql_types.lock().await;
let (names_str, values_str) =
format_values(member_names_result, member_values, &sql_types)?;
let insert_components = format!(
"INSERT OR REPLACE INTO external_{} (entity_id {}) VALUES ('{}' {})",
component.to_lowercase(),
Expand Down Expand Up @@ -329,6 +363,7 @@ fn component_names(entity_result: Option<SqliteRow>, new_component: &str) -> Res
fn format_values(
member_results: Vec<SqliteRow>,
values: Vec<FieldElement>,
sql_types: &HashMap<String, &str>,
) -> Result<(String, String)> {
let names: Result<Vec<String>> = member_results
.iter()
Expand All @@ -345,26 +380,12 @@ fn format_values(
let values: Result<Vec<String>> = values
.iter()
.zip(types?.iter())
.map(|(value, ty)| {
if sql_type(ty)? == "INTEGER" {
Ok(format!(",'{}'", value))
} else {
Ok(format!(",'{:#x}'", value))
}
.map(|(value, ty)| match sql_types.get(ty).copied() {
Some("INTEGER") => Ok(format!(",'{}'", value)),
Some("TEXT") => Ok(format!(",'{:#x}'", value)),
_ => Err(anyhow::anyhow!("Unsupported type {}", ty)),
})
.collect();

Ok((names?.join(""), values?.join("")))
}

// NOTE: If adding/removing types, corresponding change needs to be made to torii-graphql
// `src/types.rs`
fn sql_type(member_type: &str) -> Result<&str, anyhow::Error> {
match member_type {
"u8" | "u16" | "u32" | "u64" | "usize" | "bool" => Ok("INTEGER"),
"u128" | "u256" | "Cursor" | "ContractAddress" | "ClassHash" | "DateTime" | "felt252" => {
Ok("TEXT")
}
_ => Err(anyhow::anyhow!("Unknown member type {}", member_type.to_string())),
}
}
57 changes: 0 additions & 57 deletions crates/torii/graphql/src/tests/events_test.rs

This file was deleted.

6 changes: 0 additions & 6 deletions crates/torii/graphql/src/tests/fixtures/events.sql

This file was deleted.

6 changes: 0 additions & 6 deletions crates/torii/graphql/src/tests/fixtures/system_calls.sql

This file was deleted.

6 changes: 0 additions & 6 deletions crates/torii/graphql/src/tests/fixtures/systems.sql

This file was deleted.

1 change: 0 additions & 1 deletion crates/torii/graphql/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod common;
mod components_test;
mod entities_test;
mod events_test;
mod subscription_test;
5 changes: 5 additions & 0 deletions crates/torii/graphql/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub enum ScalarType {
ClassHash,
DateTime,
Felt252,
Enum,
}

impl fmt::Display for ScalarType {
Expand All @@ -37,6 +38,7 @@ impl fmt::Display for ScalarType {
ScalarType::ClassHash => write!(f, "ClassHash"),
ScalarType::DateTime => write!(f, "DateTime"),
ScalarType::Felt252 => write!(f, "felt252"),
ScalarType::Enum => write!(f, "Enum"),
}
}
}
Expand All @@ -57,6 +59,7 @@ impl ScalarType {
ScalarType::ClassHash,
ScalarType::DateTime,
ScalarType::Felt252,
ScalarType::Enum,
]
.into_iter()
.collect()
Expand All @@ -70,6 +73,7 @@ impl ScalarType {
ScalarType::U64,
ScalarType::USize,
ScalarType::Bool,
ScalarType::Enum,
]
.into_iter()
.collect()
Expand Down Expand Up @@ -114,6 +118,7 @@ impl FromStr for ScalarType {
"ClassHash" => Ok(ScalarType::ClassHash),
"DateTime" => Ok(ScalarType::DateTime),
"felt252" => Ok(ScalarType::Felt252),
"Enum" => Ok(ScalarType::Enum),
_ => Err(anyhow::anyhow!("Unknown type {}", s.to_string())),
}
}
Expand Down
Loading