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-core): store update member #2182

Merged
merged 38 commits into from
Aug 1, 2024

Conversation

Larkooo
Copy link
Collaborator

@Larkooo Larkooo commented Jul 17, 2024

support store update member for store updates that only updates a single model member values

Summary by CodeRabbit

  • New Features

    • Introduced functionality to handle events related to updating member records in the store.
    • Added a new event structure for StoreUpdateMember, facilitating detailed updates within the application.
  • Enhancements

    • Improved database interaction with a new asynchronous function for setting model members.
    • Streamlined the existence check for entities, enhancing performance and clarity.
    • Updated SQL insert logic to allow for updates to existing records, improving data handling flexibility.
    • Enhanced data modeling with a new PlayerItem structure for managing player items.

Copy link

coderabbitai bot commented Jul 17, 2024

Ohayo, Sensei!

Walkthrough

This update enhances the Torii project by introducing a new asynchronous method, set_model_member, which improves the management of model members in the database. It also features the StoreUpdateMember struct to streamline event handling for updates, ensuring data integrity and optimizing performance. Refinements to existing methods, such as renaming for clarity, further enhance the efficiency and control of entity management across the system.

Changes

File/Path Change Summary
crates/torii/core/src/sql.rs Added set_model_member function; renamed entity existence check to does_entity_exist with boolean return type.
crates/torii/core/src/processors/store_update_member.rs Introduced StoreUpdateMemberProcessor for managing updates to model members via events.
crates/dojo-core/src/world/world_contract.cairo Added StoreUpdateMember struct for enhanced event emissions related to model updates.
crates/dojo-lang/src/... Included StoreUpdateMember in JSON manifest for the world contract.
examples/spawn-and-move/manifests/... Updated JSON schemas to incorporate StoreUpdateMember, enhancing store update functionalities.
examples/spawn-and-move/manifests/release/base/dojo-world.toml Updated class hashes indicating changes in class representations.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant StoreUpdateMemberProcessor
    participant Database
    participant Sql

    User->>StoreUpdateMemberProcessor: Event with Update Member Data
    StoreUpdateMemberProcessor->>Sql: process(event, ...)
    Sql->>Database: Check if entity exists
    Database-->>Sql: Entity existence result
    Sql->>Database: Update model member
    Database-->>Sql: Update result
    Sql-->>StoreUpdateMemberProcessor: Processing result
    StoreUpdateMemberProcessor-->>User: Success/Failure response
Loading

This diagram illustrates the workflow for updating a model member when an event is received, detailing the interactions among the StoreUpdateMemberProcessor, the Sql struct, and the Database.


Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 652a1f4 and 72cc8df.

Files selected for processing (1)
  • crates/sozo/ops/src/tests/model.rs (1 hunks)
Additional comments not posted (2)
crates/sozo/ops/src/tests/model.rs (2)

Line range hint 57-69:
LGTM!

The function test_check_tag_or_read_default is unchanged and looks good.


40-41: Ohayo sensei! Verify the correctness of the new expected value.

The expected value in the assertion has been changed. Ensure that this new value aligns with the updated logic or data.


Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Jul 17, 2024

Codecov Report

Attention: Patch coverage is 28.57143% with 115 lines in your changes missing coverage. Please review.

Project coverage is 70.08%. Comparing base (8bcdc3b) to head (72cc8df).
Report is 7 commits behind head on main.

Files Patch % Lines
...s/torii/core/src/processors/store_update_member.rs 0.00% 67 Missing ⚠️
crates/torii/core/src/sql.rs 21.66% 47 Missing ⚠️
bin/torii/src/main.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2182      +/-   ##
==========================================
+ Coverage   69.82%   70.08%   +0.26%     
==========================================
  Files         340      344       +4     
  Lines       44764    45120     +356     
==========================================
+ Hits        31256    31624     +368     
+ Misses      13508    13496      -12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Larkooo Larkooo marked this pull request as ready for review July 17, 2024 16:48
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between e259d35 and 8aba41c.

Files selected for processing (4)
  • bin/torii/src/main.rs (2 hunks)
  • crates/torii/core/src/processors/mod.rs (1 hunks)
  • crates/torii/core/src/processors/store_update_member.rs (1 hunks)
  • crates/torii/core/src/sql.rs (2 hunks)
Additional context used
GitHub Check: codecov/patch
crates/torii/core/src/processors/store_update_member.rs

[warning] 28-30: crates/torii/core/src/processors/store_update_member.rs#L28-L30
Added lines #L28 - L30 were not covered by tests


[warning] 32-34: crates/torii/core/src/processors/store_update_member.rs#L32-L34
Added lines #L32 - L34 were not covered by tests


[warning] 36-38: crates/torii/core/src/processors/store_update_member.rs#L36-L38
Added lines #L36 - L38 were not covered by tests


[warning] 40-43: crates/torii/core/src/processors/store_update_member.rs#L40-L43
Added lines #L40 - L43 were not covered by tests


[warning] 54-98: crates/torii/core/src/processors/store_update_member.rs#L54-L98
Added lines #L54 - L98 were not covered by tests

bin/torii/src/main.rs

[warning] 176-176: bin/torii/src/main.rs#L176
Added line #L176 was not covered by tests

crates/torii/core/src/sql.rs

[warning] 274-292: crates/torii/core/src/sql.rs#L274-L292
Added lines #L274 - L292 were not covered by tests


[warning] 294-295: crates/torii/core/src/sql.rs#L294-L295
Added lines #L294 - L295 were not covered by tests

Additional comments not posted (1)
crates/torii/core/src/processors/mod.rs (1)

15-15: Module store_update_member added successfully.

This change is consistent with the PR's objective to enhance store update functionalities.

However, ensure that the new module integrates seamlessly with the existing system.

Comment on lines 16 to 98
pub(crate) const LOG_TARGET: &str = "torii_core::processors::store_update_record";

const MEMBER_INDEX: usize = 2;

#[derive(Default, Debug)]
pub struct StoreUpdateMemberProcessor;

#[async_trait]
impl<P> EventProcessor<P> for StoreUpdateMemberProcessor
where
P: Provider + Send + Sync + std::fmt::Debug,
{
fn event_key(&self) -> String {
"StoreUpdateMember".to_string()
}

fn validate(&self, event: &Event) -> bool {
if event.keys.len() > 1 {
info!(
target: LOG_TARGET,
event_key = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_key(self),
invalid_keys = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_keys_as_string(self, event),
"Invalid event keys."
);
return false;
}
true
}

async fn process(
&self,
_world: &WorldContractReader<P>,
db: &mut Sql,
_block_number: u64,
block_timestamp: u64,
_transaction_receipt: &TransactionReceiptWithBlockInfo,
_event_id: &str,
event: &Event,
) -> Result<(), Error> {
let selector = event.data[MODEL_INDEX];
let entity_id = event.data[ENTITY_ID_INDEX];
let member_selector = event.data[MEMBER_INDEX];

let model = db.model(selector).await?;

info!(
target: LOG_TARGET,
name = %model.name(),
entity_id = format!("{:#x}", entity_id),
"Store update record.",
);

let values_start = MEMBER_INDEX + 1;
let values_end: usize =
values_start + event.data[values_start].to_usize().context("invalid usize")?;

// Skip the length to only get the values as they will be deserialized.
let values = event.data[values_start + 1..=values_end].to_vec();

let tag = naming::get_tag(model.namespace(), model.name());

// Keys are read from the db, since we don't have access to them when only
// the entity id is passed.
let keys = db.get_entity_keys(entity_id, &tag).await?;
let mut keys_and_unpacked = [keys, values].concat();

let schema = model.schema().await?;
let mut ty = schema
.as_struct()
.expect("model schema must be a struct")
.children
.iter()
.find(|c| {
get_selector_from_name(&c.name).expect("invalid selector for member name")
== member_selector
})
.context("member not found")?
.ty
.clone();
ty.deserialize(&mut keys_and_unpacked)?;

db.set_model_member(entity_id, &schema.name(), &ty, block_timestamp).await
}
Copy link

Choose a reason for hiding this comment

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

Comprehensive implementation of StoreUpdateMemberProcessor.

The processor is well-implemented with methods for event validation and processing. However, the codecov warnings indicate missing test coverage which is crucial for ensuring the functionality works as expected.

+ // TODO: Add unit tests to cover the new functionality.

Would you like me to help in writing some initial unit tests or open a GitHub issue to track this task?

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub(crate) const LOG_TARGET: &str = "torii_core::processors::store_update_record";
const MEMBER_INDEX: usize = 2;
#[derive(Default, Debug)]
pub struct StoreUpdateMemberProcessor;
#[async_trait]
impl<P> EventProcessor<P> for StoreUpdateMemberProcessor
where
P: Provider + Send + Sync + std::fmt::Debug,
{
fn event_key(&self) -> String {
"StoreUpdateMember".to_string()
}
fn validate(&self, event: &Event) -> bool {
if event.keys.len() > 1 {
info!(
target: LOG_TARGET,
event_key = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_key(self),
invalid_keys = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_keys_as_string(self, event),
"Invalid event keys."
);
return false;
}
true
}
async fn process(
&self,
_world: &WorldContractReader<P>,
db: &mut Sql,
_block_number: u64,
block_timestamp: u64,
_transaction_receipt: &TransactionReceiptWithBlockInfo,
_event_id: &str,
event: &Event,
) -> Result<(), Error> {
let selector = event.data[MODEL_INDEX];
let entity_id = event.data[ENTITY_ID_INDEX];
let member_selector = event.data[MEMBER_INDEX];
let model = db.model(selector).await?;
info!(
target: LOG_TARGET,
name = %model.name(),
entity_id = format!("{:#x}", entity_id),
"Store update record.",
);
let values_start = MEMBER_INDEX + 1;
let values_end: usize =
values_start + event.data[values_start].to_usize().context("invalid usize")?;
// Skip the length to only get the values as they will be deserialized.
let values = event.data[values_start + 1..=values_end].to_vec();
let tag = naming::get_tag(model.namespace(), model.name());
// Keys are read from the db, since we don't have access to them when only
// the entity id is passed.
let keys = db.get_entity_keys(entity_id, &tag).await?;
let mut keys_and_unpacked = [keys, values].concat();
let schema = model.schema().await?;
let mut ty = schema
.as_struct()
.expect("model schema must be a struct")
.children
.iter()
.find(|c| {
get_selector_from_name(&c.name).expect("invalid selector for member name")
== member_selector
})
.context("member not found")?
.ty
.clone();
ty.deserialize(&mut keys_and_unpacked)?;
db.set_model_member(entity_id, &schema.name(), &ty, block_timestamp).await
}
pub(crate) const LOG_TARGET: &str = "torii_core::processors::store_update_record";
const MEMBER_INDEX: usize = 2;
#[derive(Default, Debug)]
pub struct StoreUpdateMemberProcessor;
#[async_trait]
impl<P> EventProcessor<P> for StoreUpdateMemberProcessor
where
P: Provider + Send + Sync + std::fmt::Debug,
{
fn event_key(&self) -> String {
"StoreUpdateMember".to_string()
}
fn validate(&self, event: &Event) -> bool {
if event.keys.len() > 1 {
info!(
target: LOG_TARGET,
event_key = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_key(self),
invalid_keys = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_keys_as_string(self, event),
"Invalid event keys."
);
return false;
}
true
}
async fn process(
&self,
_world: &WorldContractReader<P>,
db: &mut Sql,
_block_number: u64,
block_timestamp: u64,
_transaction_receipt: &TransactionReceiptWithBlockInfo,
_event_id: &str,
event: &Event,
) -> Result<(), Error> {
let selector = event.data[MODEL_INDEX];
let entity_id = event.data[ENTITY_ID_INDEX];
let member_selector = event.data[MEMBER_INDEX];
let model = db.model(selector).await?;
info!(
target: LOG_TARGET,
name = %model.name(),
entity_id = format!("{:#x}", entity_id),
"Store update record.",
);
let values_start = MEMBER_INDEX + 1;
let values_end: usize =
values_start + event.data[values_start].to_usize().context("invalid usize")?;
// Skip the length to only get the values as they will be deserialized.
let values = event.data[values_start + 1..=values_end].to_vec();
let tag = naming::get_tag(model.namespace(), model.name());
// Keys are read from the db, since we don't have access to them when only
// the entity id is passed.
let keys = db.get_entity_keys(entity_id, &tag).await?;
let mut keys_and_unpacked = [keys, values].concat();
let schema = model.schema().await?;
let mut ty = schema
.as_struct()
.expect("model schema must be a struct")
.children
.iter()
.find(|c| {
get_selector_from_name(&c.name).expect("invalid selector for member name")
== member_selector
})
.context("member not found")?
.ty
.clone();
ty.deserialize(&mut keys_and_unpacked)?;
db.set_model_member(entity_id, &schema.name(), &ty, block_timestamp).await
}
}
// TODO: Add unit tests to cover the new functionality.
Tools
GitHub Check: codecov/patch

[warning] 28-30: crates/torii/core/src/processors/store_update_member.rs#L28-L30
Added lines #L28 - L30 were not covered by tests


[warning] 32-34: crates/torii/core/src/processors/store_update_member.rs#L32-L34
Added lines #L32 - L34 were not covered by tests


[warning] 36-38: crates/torii/core/src/processors/store_update_member.rs#L36-L38
Added lines #L36 - L38 were not covered by tests


[warning] 40-43: crates/torii/core/src/processors/store_update_member.rs#L40-L43
Added lines #L40 - L43 were not covered by tests


[warning] 54-98: crates/torii/core/src/processors/store_update_member.rs#L54-L98
Added lines #L54 - L98 were not covered by tests

bin/torii/src/main.rs Show resolved Hide resolved
Comment on lines 274 to 295
pub async fn set_model_member(
&mut self,
entity_id: Felt,
model_tag: &str,
member: &Ty,
block_timestamp: u64,
) -> Result<()> {
let entity_id = format!("{:#x}", entity_id);
let path = vec![model_tag.to_string()];
// update model member
self.build_set_entity_queries_recursive(
path,
&entity_id,
(&entity_id, false),
member,
block_timestamp,
&vec![],
);
self.query_queue.execute_all().await?;

Ok(())
}
Copy link

Choose a reason for hiding this comment

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

Robust implementation of set_model_member.

The function is well-implemented and crucial for updating model members. However, it lacks test coverage, which is essential for ensuring its reliability and correctness.

+ // TODO: Add unit tests to cover `set_model_member`.

Would you like assistance in creating unit tests for this function, or should I open a GitHub issue to track this task?

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub async fn set_model_member(
&mut self,
entity_id: Felt,
model_tag: &str,
member: &Ty,
block_timestamp: u64,
) -> Result<()> {
let entity_id = format!("{:#x}", entity_id);
let path = vec![model_tag.to_string()];
// update model member
self.build_set_entity_queries_recursive(
path,
&entity_id,
(&entity_id, false),
member,
block_timestamp,
&vec![],
);
self.query_queue.execute_all().await?;
Ok(())
}
pub async fn set_model_member(
&mut self,
entity_id: Felt,
model_tag: &str,
member: &Ty,
block_timestamp: u64,
) -> Result<()> {
let entity_id = format!("{:#x}", entity_id);
let path = vec![model_tag.to_string()];
// update model member
self.build_set_entity_queries_recursive(
path,
&entity_id,
(&entity_id, false),
member,
block_timestamp,
&vec![],
);
self.query_queue.execute_all().await?;
Ok(())
}
// TODO: Add unit tests to cover `set_model_member`.
Tools
GitHub Check: codecov/patch

[warning] 274-292: crates/torii/core/src/sql.rs#L274-L292
Added lines #L274 - L292 were not covered by tests


[warning] 294-295: crates/torii/core/src/sql.rs#L294-L295
Added lines #L294 - L295 were not covered by tests

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 8aba41c and 65b2c39.

Files selected for processing (1)
  • crates/torii/core/src/processors/store_update_member.rs (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • crates/torii/core/src/processors/store_update_member.rs

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 65b2c39 and b54901c.

Files selected for processing (1)
  • crates/torii/core/src/processors/store_update_member.rs (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • crates/torii/core/src/processors/store_update_member.rs

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between b54901c and 349b327.

Files selected for processing (2)
  • crates/torii/core/src/processors/store_update_member.rs (1 hunks)
  • crates/torii/core/src/sql.rs (4 hunks)
Files skipped from review as they are similar to previous changes (1)
  • crates/torii/core/src/processors/store_update_member.rs
Additional comments not posted (2)
crates/torii/core/src/sql.rs (2)

Line range hint 586-692:
Visibility change to build_set_entity_queries_recursive is appropriate.

The visibility change to build_set_entity_queries_recursive is appropriate and necessary for its usage in other parts of the codebase.

However, ensure that all function calls to build_set_entity_queries_recursive are correctly updated to reflect its new visibility.

Verification successful

Visibility change to build_set_entity_queries_recursive is correctly reflected.

The visibility change to build_set_entity_queries_recursive is appropriate and has been correctly updated in all occurrences within the file.

  • All instances of build_set_entity_queries_recursive are within crates/torii/core/src/sql.rs and reflect the updated visibility.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `build_set_entity_queries_recursive` are correctly updated.

# Test: Search for the function usage. Expect: Only occurrences of the updated visibility.
rg --type rust -A 5 $'build_set_entity_queries_recursive'

Length of output: 3292


276-299: LGTM! But verify the function usage in the codebase.

The code changes are approved.

However, ensure that all function calls to set_model_member match the new signature.

Verification successful

Function usage matches the new signature.

The function call to set_model_member in store_update_member.rs matches the new signature correctly.

  • entity_id is of type Felt.
  • false is of type bool.
  • schema.name() returns a &str.
  • ty is of type Ty.
  • event_id is of type &str.
  • block_timestamp is of type u64.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `set_model_member` match the new signature.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type rust -A 5 $'set_model_member'

Length of output: 648


Script:

#!/bin/bash
# Description: Extract the types of the variables used in the set_model_member function call in store_update_member.rs

# Extract the definition of the function where set_model_member is called
rg --type rust -A 20 'fn ' crates/torii/core/src/processors/store_update_member.rs

# Extract the type of `schema`
rg --type rust -A 5 'schema' crates/torii/core/src/processors/store_update_member.rs

# Extract the type of `ty`
rg --type rust -A 5 'ty' crates/torii/core/src/processors/store_update_member.rs

# Extract the type of `event_id`
rg --type rust -A 5 'event_id' crates/torii/core/src/processors/store_update_member.rs

# Extract the type of `block_timestamp`
rg --type rust -A 5 'block_timestamp' crates/torii/core/src/processors/store_update_member.rs

Length of output: 4033

Comment on lines 276 to 299
pub async fn set_model_member(
&mut self,
entity_id: Felt,
is_event_message: bool,
model_tag: &str,
member: &Ty,
event_id: &str,
block_timestamp: u64,
) -> Result<()> {
let entity_id = format!("{:#x}", entity_id);
let path = vec![model_tag.to_string()];
// update model member
self.build_set_entity_queries_recursive(
path,
event_id,
(&entity_id, is_event_message),
member,
block_timestamp,
&vec![],
);
self.query_queue.execute_all().await?;

Ok(())
}
Copy link

Choose a reason for hiding this comment

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

Reminder: Add tests.

The set_model_member function is well-implemented and crucial for updating model members. However, it lacks test coverage, which is essential for ensuring its reliability and correctness.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 349b327 and 9dd48d8.

Files selected for processing (1)
  • crates/torii/core/src/sql.rs (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • crates/torii/core/src/sql.rs

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9dd48d8 and b0d9fd5.

Files selected for processing (1)
  • crates/torii/core/src/sql.rs (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • crates/torii/core/src/sql.rs

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between b0d9fd5 and 71af001.

Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
Files selected for processing (13)
  • crates/dojo-core/src/world.cairo (3 hunks)
  • crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json (2 hunks)
  • crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/dojo-world.toml (1 hunks)
  • crates/dojo-world/src/contracts/abi/world.rs (2 hunks)
  • crates/torii/core/src/processors/store_update_member.rs (1 hunks)
  • examples/spawn-and-move/Scarb.toml (1 hunks)
  • examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json (2 hunks)
  • examples/spawn-and-move/manifests/dev/base/dojo-world.toml (1 hunks)
  • examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json (2 hunks)
  • examples/spawn-and-move/manifests/dev/deployment/manifest.json (8 hunks)
  • examples/spawn-and-move/manifests/dev/deployment/manifest.toml (5 hunks)
  • examples/spawn-and-move/manifests/release/base/abis/dojo-world.json (2 hunks)
  • examples/spawn-and-move/manifests/release/base/dojo-world.toml (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • crates/torii/core/src/processors/store_update_member.rs
Additional comments not posted (29)
crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/dojo-world.toml (1)

2-3: Verify the correctness of the new hash values.

The class_hash and original_class_hash values have been updated. Ensure that these new hash values are correct and consistent with the updated class definitions.

examples/spawn-and-move/manifests/dev/base/dojo-world.toml (1)

2-3: Verify the correctness of the new hash values.

The class_hash and original_class_hash values have been updated. Ensure that these new hash values are correct and consistent with the updated class definitions.

examples/spawn-and-move/manifests/release/base/dojo-world.toml (1)

2-3: Verify the correctness of the new hash values.

The class_hash and original_class_hash values have been updated. Ensure that these new hash values are correct and consistent with the updated class definitions.

examples/spawn-and-move/Scarb.toml (1)

46-46: Verify the correctness of the new world address.

The world_address value has been updated. Ensure that this new address is correct and consistent with the intended environment.

examples/spawn-and-move/manifests/dev/deployment/manifest.toml (7)

3-4: Verify the correctness of the new class hashes.

Ensure that the new class_hash and original_class_hash values are correct and consistent with the intended updates.


6-6: Verify the correctness of the new address.

Ensure that the new address value is correct and consistent with the intended updates.


7-7: Verify the correctness of the new transaction hash.

Ensure that the new transaction_hash value is correct and consistent with the intended updates.


26-26: Verify the correctness of the new address.

Ensure that the new address value is correct and consistent with the intended updates.


43-43: Verify the correctness of the new address.

Ensure that the new address value is correct and consistent with the intended updates.


57-57: Verify the correctness of the new address.

Ensure that the new address value is correct and consistent with the intended updates.


71-71: Verify the correctness of the new address.

Ensure that the new address value is correct and consistent with the intended updates.

crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json (2)

978-1004: Verify the correctness and consistency of the new event structure.

Ensure that the structure of the new event "StoreUpdateMember" is correct and consistent with the existing events.


1186-1190: Verify the correctness and consistency of the new event reference.

Ensure that the reference to the new event "StoreUpdateMember" in the "events" section is correct and consistent with the existing events.

examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json (2)

978-1004: Verify the correctness and consistency of the new event structure.

Ensure that the structure of the new event "StoreUpdateMember" is correct and consistent with the existing events.


1186-1190: Verify the correctness and consistency of the new event reference.

Ensure that the reference to the new event "StoreUpdateMember" in the "events" section is correct and consistent with the existing events.

examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json (2)

978-1004: New event definition looks good.

The new event StoreUpdateMember is well-defined with appropriate member types.


1186-1190: Integration of new event in enum looks good.

The StoreUpdateMember event is correctly integrated within the dojo::world::world::Event enum.

examples/spawn-and-move/manifests/release/base/abis/dojo-world.json (2)

978-1004: LGTM! New event StoreUpdateMember is well-defined.

The new event StoreUpdateMember with members table, entity_id, member_selector, and values is consistent with the existing event definitions.


1186-1190: LGTM! New event StoreUpdateMember added to events array.

The addition of StoreUpdateMember to the events array ensures proper recognition and processing.

crates/dojo-world/src/contracts/abi/world.rs (2)

984-1010: LGTM! New event StoreUpdateMember is well-defined.

The new event StoreUpdateMember with members table, entity_id, member_selector, and values is consistent with the existing event definitions.


1192-1196: LGTM! New event StoreUpdateMember added to abigen! macro.

The addition of StoreUpdateMember to the abigen! macro ensures proper recognition and processing.

crates/dojo-core/src/world.cairo (3)

234-240: LGTM! Struct definition is correct.

The StoreUpdateMember struct is properly defined with appropriate field types.


872-877: LGTM! Function changes are correct.

The set_entity function correctly handles the ModelIndex::MemberId pattern match and emits the StoreUpdateMember event.


159-159: LGTM! Event emission logic is correct.

The emit function correctly handles custom event emissions.

examples/spawn-and-move/manifests/dev/deployment/manifest.json (5)

4-5: Verify the correctness of the new class hash values.

Ensure that the new class_hash and original_class_hash values are correct and consistent with the intended updates.

Verification successful

The new class hash values are correctly updated and consistent.

The class_hash and original_class_hash values are identical and correctly formatted as per the intended updates in the manifest.json file.

  • class_hash: 0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820
  • original_class_hash: 0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the correctness of the new class hash values.

# Test: Search for the new class hash values. Expect: No mismatches.
rg --type json '0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820'

Length of output: 391


1191-1195: Verify the correctness and completeness of the new event variant StoreUpdateMember.

Ensure that the new event variant StoreUpdateMember is correct and complete with all necessary attributes.

Verification successful

Verify the correctness and completeness of the new event variant StoreUpdateMember.

The StoreUpdateMember event variant is correctly integrated and consistently formatted across multiple files in the codebase:

  • examples/spawn-and-move/manifests/dev/deployment/manifest.json
  • examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json
  • examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json
  • examples/spawn-and-move/manifests/release/base/abis/dojo-world.json
  • crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the correctness and completeness of the new event variant `StoreUpdateMember`.

# Test: Search for the new event variant. Expect: No mismatches.
rg --type json 'StoreUpdateMember'

Length of output: 1861


1224-1224: Verify the correctness of the new address value.

Ensure that the new address value is correct and consistent with the intended updates.


1225-1225: Verify the correctness of the new transaction hash value.

Ensure that the new transaction_hash value is correct and consistent with the intended updates.


983-1009: Verify the correctness and completeness of the new event definition StoreUpdateMember.

Ensure that the new event definition StoreUpdateMember is correct and complete with all necessary member attributes.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 71af001 and 9343249.

Files selected for processing (7)
  • crates/dojo-lang/src/event.rs (1 hunks)
  • examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml (1 hunks)
  • examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-others-61de2c18.toml (1 hunks)
  • examples/spawn-and-move/manifests/dev/deployment/manifest.json (8 hunks)
  • examples/spawn-and-move/manifests/dev/deployment/manifest.toml (5 hunks)
  • examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml (1 hunks)
  • examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-others-61de2c18.toml (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • examples/spawn-and-move/manifests/dev/deployment/manifest.json
  • examples/spawn-and-move/manifests/dev/deployment/manifest.toml
Additional comments not posted (6)
examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-others-61de2c18.toml (1)

2-3: Update class_hash and original_class_hash values.

The new class_hash and original_class_hash values have been updated correctly. Ensure that these new values are consistent with the intended contract updates.

Verification successful

Update class_hash and original_class_hash values.

The new class_hash and original_class_hash values have been updated correctly across multiple files in the repository. The updated values are consistent with the intended contract updates.

  • examples/spawn-and-move/manifests/dev/deployment/manifest.toml
  • examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-others-61de2c18.toml
  • examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-others-61de2c18.toml
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the consistency of new class_hash and original_class_hash values.

# Test: Search for the new hash values in the repository. Expect: Consistent usage of the new hash values.
rg --type toml '0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4'

Length of output: 1074

examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-others-61de2c18.toml (1)

2-3: Update class_hash and original_class_hash values.

The new class_hash and original_class_hash values have been updated correctly. Ensure that these new values are consistent with the intended contract updates.

Verification successful

The new class_hash and original_class_hash values are consistent.

The specific hash values 0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4 are used consistently across the related files in the repository.

  • examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-others-61de2c18.toml
  • examples/spawn-and-move/manifests/dev/deployment/manifest.toml
  • examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-others-61de2c18.toml

These values align with the intended contract updates.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the consistency of new class_hash and original_class_hash values.

# Test: Search for the new hash values in the repository. Expect: Consistent usage of the new hash values.
rg --type toml '0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4'

Length of output: 1074


Script:

#!/bin/bash
# Description: Verify if there are any other class_hash or original_class_hash values in the repository.

# Test: Search for any class_hash or original_class_hash values in the repository.
rg --type toml 'class_hash = "0x' --type toml 'original_class_hash = "0x'

Length of output: 141


Script:

#!/bin/bash
# Description: Verify if there are any other class_hash or original_class_hash values in the repository.

# Test: Search for any class_hash values in the repository.
rg --type toml 'class_hash = "0x'

# Test: Search for any original_class_hash values in the repository.
rg --type toml 'original_class_hash = "0x'

Length of output: 30814

examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml (1)

2-3: Update class_hash and original_class_hash values.

The new class_hash and original_class_hash values have been updated correctly. Ensure that these new values are consistent with the intended contract updates.

examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml (1)

2-3: Update class_hash and original_class_hash values.

The new class_hash and original_class_hash values have been updated correctly. Ensure that these new values are consistent with the intended contract updates.

Verification successful

The new class_hash and original_class_hash values are used consistently across the relevant files.

  • examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml
  • examples/spawn-and-move/manifests/dev/deployment/manifest.toml
  • examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml
  • examples/spawn-and-move/manifests/dev/deployment/manifest.json
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the consistency of new class_hash and original_class_hash values.

# Test: Search for the new hash values in the repository. Expect: Consistent usage of the new hash values.
rg --type toml '0x7b59e8f1039dd99e39af7695bbbd5bcc4ffd7852f54576fe4acf89590298c01'

Length of output: 1085


Script:

#!/bin/bash
# Description: Search for references to the intended contract updates that mention the class_hash and original_class_hash values.

# Test: Search for the hash values in the repository, including documentation and other relevant files.
rg '0x7b59e8f1039dd99e39af7695bbbd5bcc4ffd7852f54576fe4acf89590298c01'

Length of output: 1386

crates/dojo-lang/src/event.rs (2)

Line range hint 1-84:
LGTM!

The rest of the handle_event_struct function remains unchanged and appears to be logically consistent and correct.

Also applies to: 87-146


85-86: Verify the definition and accessibility of selector method.

The change replaces selector!("$struct_name$") with dojo::model::Model::<$struct_name$>::selector(). Ensure that the selector method is correctly defined and accessible within dojo::model::Model.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Comment on lines 45 to 106
async fn process(
&self,
_world: &WorldContractReader<P>,
db: &mut Sql,
_block_number: u64,
block_timestamp: u64,
_transaction_receipt: &TransactionReceiptWithBlockInfo,
event_id: &str,
event: &Event,
) -> Result<(), Error> {
let selector = event.data[MODEL_INDEX];
let entity_id = event.data[ENTITY_ID_INDEX];
let member_selector = event.data[MEMBER_INDEX];

let model = db.model(selector).await?;
let schema = model.schema().await?;

let mut member = schema
.as_struct()
.expect("model schema must be a struct")
.children
.iter()
.find(|c| {
get_selector_from_name(&c.name).expect("invalid selector for member name")
== member_selector
})
.context("member not found")?
.clone();

info!(
target: LOG_TARGET,
name = %model.name(),
entity_id = format!("{:#x}", entity_id),
member = %member.name,
"Store update member.",
);

let values_start = MEMBER_INDEX + 1;
let values_end: usize =
values_start + event.data[values_start].to_usize().context("invalid usize")?;

// Skip the length to only get the values as they will be deserialized.
let mut values = event.data[values_start + 1..=values_end].to_vec();

let tag = naming::get_tag(model.namespace(), model.name());

if !db.does_entity_exist(tag.clone(), entity_id).await? {
warn!(
target: LOG_TARGET,
tag,
entity_id = format!("{:#x}", entity_id),
"Entity not found, must be set before updating a member.",
);

return Ok(());
}

member.ty.deserialize(&mut values)?;

db.set_model_member(entity_id, false, &schema.name(), &member, event_id, block_timestamp)
.await
}
Copy link

Choose a reason for hiding this comment

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

Comprehensive implementation of process.

The process function is well-implemented with clear steps for handling store update member events. However, the codecov warnings indicate missing test coverage which is crucial for ensuring the functionality works as expected.

+ // TODO: Add unit tests to cover the new functionality.

Would you like me to help in writing some initial unit tests or open a GitHub issue to track this task?

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async fn process(
&self,
_world: &WorldContractReader<P>,
db: &mut Sql,
_block_number: u64,
block_timestamp: u64,
_transaction_receipt: &TransactionReceiptWithBlockInfo,
event_id: &str,
event: &Event,
) -> Result<(), Error> {
let selector = event.data[MODEL_INDEX];
let entity_id = event.data[ENTITY_ID_INDEX];
let member_selector = event.data[MEMBER_INDEX];
let model = db.model(selector).await?;
let schema = model.schema().await?;
let mut member = schema
.as_struct()
.expect("model schema must be a struct")
.children
.iter()
.find(|c| {
get_selector_from_name(&c.name).expect("invalid selector for member name")
== member_selector
})
.context("member not found")?
.clone();
info!(
target: LOG_TARGET,
name = %model.name(),
entity_id = format!("{:#x}", entity_id),
member = %member.name,
"Store update member.",
);
let values_start = MEMBER_INDEX + 1;
let values_end: usize =
values_start + event.data[values_start].to_usize().context("invalid usize")?;
// Skip the length to only get the values as they will be deserialized.
let mut values = event.data[values_start + 1..=values_end].to_vec();
let tag = naming::get_tag(model.namespace(), model.name());
if !db.does_entity_exist(tag.clone(), entity_id).await? {
warn!(
target: LOG_TARGET,
tag,
entity_id = format!("{:#x}", entity_id),
"Entity not found, must be set before updating a member.",
);
return Ok(());
}
member.ty.deserialize(&mut values)?;
db.set_model_member(entity_id, false, &schema.name(), &member, event_id, block_timestamp)
.await
}
async fn process(
&self,
_world: &WorldContractReader<P>,
db: &mut Sql,
_block_number: u64,
block_timestamp: u64,
_transaction_receipt: &TransactionReceiptWithBlockInfo,
event_id: &str,
event: &Event,
) -> Result<(), Error> {
let selector = event.data[MODEL_INDEX];
let entity_id = event.data[ENTITY_ID_INDEX];
let member_selector = event.data[MEMBER_INDEX];
let model = db.model(selector).await?;
let schema = model.schema().await?;
let mut member = schema
.as_struct()
.expect("model schema must be a struct")
.children
.iter()
.find(|c| {
get_selector_from_name(&c.name).expect("invalid selector for member name")
== member_selector
})
.context("member not found")?
.clone();
info!(
target: LOG_TARGET,
name = %model.name(),
entity_id = format!("{:#x}", entity_id),
member = %member.name,
"Store update member.",
);
let values_start = MEMBER_INDEX + 1;
let values_end: usize =
values_start + event.data[values_start].to_usize().context("invalid usize")?;
// Skip the length to only get the values as they will be deserialized.
let mut values = event.data[values_start + 1..=values_end].to_vec();
let tag = naming::get_tag(model.namespace(), model.name());
if !db.does_entity_exist(tag.clone(), entity_id).await? {
warn!(
target: LOG_TARGET,
tag,
entity_id = format!("{:#x}", entity_id),
"Entity not found, must be set before updating a member.",
);
return Ok(());
}
member.ty.deserialize(&mut values)?;
db.set_model_member(entity_id, false, &schema.name(), &member, event_id, block_timestamp)
.await
}
// TODO: Add unit tests to cover the new functionality.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Outside diff range, codebase verification and nitpick comments (1)
crates/torii/core/src/sql.rs (1)

Line range hint 591-680:
Optimize the logic for updating members.

The current logic for updating members could be optimized to reduce redundancy and improve readability.

-                let statement = if is_store_update_member {
-                    // row has to exist. update it directly
-                    format!(
-                        "UPDATE [{table_id}] SET {updates} WHERE entity_id = ?",
-                        table_id = table_id,
-                        updates = columns
-                            .iter()
-                            // skip id column
-                            .skip(1)
-                            .zip(placeholders.iter().skip(1))
-                            .map(|(column, placeholder)| format!("{} = {}", column, placeholder))
-                            .collect::<Vec<String>>()
-                            .join(", ")
-                    )
-                } else {
-                    format!(
-                        "INSERT OR REPLACE INTO [{table_id}] ({}) VALUES ({})",
-                        columns.join(","),
-                        placeholders.join(",")
-                    )
-                };
+                let statement = format!(
+                    "{} INTO [{table_id}] ({}) VALUES ({})",
+                    if is_store_update_member { "UPDATE" } else { "INSERT OR REPLACE" },
+                    columns.join(","),
+                    placeholders.join(",")
+                );

crates/torii/core/src/sql.rs Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Outside diff range, codebase verification and nitpick comments (2)
crates/torii/core/src/sql.rs (2)

418-424: Add a comment explaining the SQL query.

Adding a comment to explain the SQL query would enhance code readability and maintainability.

+        // Check if the entity exists in the specified model table.

595-601: Add comments to explain complex logic.

Adding comments to explain the complex logic in this function would enhance code readability and maintainability.

+        // Extract the entity ID and event message flag.
+        let (entity_id, is_event_message) = entity_id;

@@ -271,6 +274,35 @@ impl Sql {
Ok(())
}

pub async fn set_model_member(
Copy link

Choose a reason for hiding this comment

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

Ohayo, Sensei! Reminder: Add tests.

The set_model_member function is well-implemented and crucial for updating model members. However, it lacks test coverage, which is essential for ensuring its reliability and correctness.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Copy link
Collaborator

@glihm glihm left a comment

Choose a reason for hiding this comment

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

Thanks @Larkooo for the fixes here. @lambda-0x we will plan testing of this at both integration and unit.

@Larkooo Larkooo merged commit f490222 into dojoengine:main Aug 1, 2024
14 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants