Skip to content

Refactor sql generation logic with SqlStatement #2262

Merged
findolor merged 33 commits intomainfrom
local-db-stmt-refactor
Oct 31, 2025
Merged

Refactor sql generation logic with SqlStatement #2262
findolor merged 33 commits intomainfrom
local-db-stmt-refactor

Conversation

@findolor
Copy link
Copy Markdown
Collaborator

@findolor findolor commented Oct 22, 2025

Motivation

See issues:

Solution

  • Add new SqlStatementBatch module for multiple SqlStatements
  • Add execute_batch function to LocalDbQueryExecutor trait and implement for executors
  • Update sql insert command generators to use SqlStatement natively
  • Update call sites to use the new batch logic
  • Remove cli commands that are now unused with the new SqlStatement and batching logic
  • Update tests

Checks

By submitting this for review, I'm confirming I've done the following:

  • made this PR as small as possible
  • unit-tested any new functionality
  • linked any relevant issues or PRs
  • included screenshots (if this involves a front-end change)

Summary by CodeRabbit

Release Notes

  • Removed Features

    • Removed fetch-events, decode-events, decoded-events-to-sql, tokens-fetch, and tokens-to-sql CLI subcommands for local database operations
    • sync and dump subcommands remain available
  • Improvements

    • Enhanced local database execution with improved batch processing and parameterized query support

@findolor findolor added this to the LocalDB Implementation milestone Oct 22, 2025
@findolor findolor requested a review from hardyjosh October 22, 2025 18:06
@findolor findolor requested a review from 0xgleb October 22, 2025 18:06
@findolor findolor self-assigned this Oct 22, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 22, 2025

Walkthrough

This PR removes five local_db CLI subcommands (FetchEvents, DecodeEvents, DecodedEventsToSql, TokensFetch, TokensToSql) and refactors the SQL generation layer from string-based to structured, parameterized statement batches. It introduces SqlStatementBatch and SqlStatement types, updates executors to support transactional batch execution, and adjusts sync and query pipelines to consume batches instead of raw SQL strings.

Changes

Cohort / File(s) Summary
CLI command removal
crates/cli/src/commands/local_db/{decode_events,decoded_events_to_sql,fetch_events,tokens_fetch,tokens_to_sql}.rs
Removed five modules implementing local_db CLI subcommands: DecodeEvents, DecodedEventsToSql, FetchEvents, TokensFetch, TokensToSql, including their execute methods, helper structs, and test suites.
Local_db module exports
crates/cli/src/commands/local_db/mod.rs
Removed pub mod declarations and public use statements for: decode_events, decoded_events_to_sql, fetch_events, tokens_fetch, tokens_to_sql. Retained: executor, dump, sync modules.
CLI main dispatch
crates/cli/src/lib.rs
Removed LocalDb enum variants: FetchEvents, DecodeEvents, DecodedEventsToSql, TokensFetch, TokensToSql. Updated LocalDb::execute match arms to handle only Dump and Sync. Updated imports to match.
SQL statement types
crates/common/src/local_db/query/{sql_statement.rs,sql_statement_batch.rs}
Added SqlValue::U64 variant and From impl; added SqlStatement::new_with_params constructor. Introduced new SqlStatementBatch type with construction (new, with_statements), mutation (add, extend), transaction handling (ensure_transaction, is_transaction), iteration, and conversion methods.
Query module structure
crates/common/src/local_db/query/mod.rs
Added pub mod sql_statement_batch and re-export pub use sql_statement_batch::SqlStatementBatch.
Query executor API
crates/common/src/local_db/query/executor.rs
Added new public async method execute_batch(&self, batch: &SqlStatementBatch) to LocalDbQueryExecutor trait.
SQL generation refactor
crates/common/src/local_db/insert.rs
Renamed and refactored public functions: decoded_events_to_sql → decoded_events_to_statements (returns SqlStatementBatch); raw_events_to_sql → raw_events_to_statements (returns SqlStatementBatch); generate_erc20_tokens_sql → generate_erc20_token_statements (returns SqlStatementBatch). Replaced string-based SQL assembly with parameterized SqlStatement/SqlStatementBatch builders for all event types.
LocalDb public API
crates/common/src/local_db/mod.rs
Renamed methods: decoded_events_to_sql → decoded_events_to_statements (removes end_block/prefix_sql params, returns SqlStatementBatch); raw_events_to_sql → raw_events_to_statements (returns SqlStatementBatch). Updated internal delegation function names and imports.
Sync coordination
crates/common/src/local_db/sync.rs
Refactored to batch-based SQL execution: TokenPrepResult.tokens_prefix_sql changed from String to SqlStatementBatch; prepare_erc20_tokens_prefix now builds batches; execution uses execute_batch instead of per-statement query_text. Updated token generation call: generate_erc20_tokens_sql → generate_erc20_token_statements.
Sync trait and data source
crates/cli/src/commands/local_db/sync/data_source.rs
Updated SyncDataSource trait: events_to_sql now returns Result (removed end_block/prefix_sql params); replaced raw_events_to_sql with raw_events_to_statements returning Result. Updated LocalDb impl to match new signatures.
Sync runner apply phase
crates/cli/src/commands/local_db/sync/runner/apply.rs
Refactored prepare_sql: returns Result instead of Result. Now uses raw_events_to_statements, builds batch via extend(), and wraps in transaction. Updated mock and test implementations to use SqlStatement/SqlStatementBatch.
Sync runner orchestration
crates/cli/src/commands/local_db/sync/runner/mod.rs
Updated to use execute_batch(&sql_batch) instead of query_text(&SqlStatement::new(sql)). Adjusted SyncDataSource trait signatures in test mocks to return SqlStatementBatch and simplified parameters.
Sync runner window phase
crates/cli/src/commands/local_db/sync/runner/window.rs
Updated SyncDataSource trait method signatures in tests: events_to_sql and raw_events_to_statements now return Result. Updated mock implementations accordingly.
Sync token metadata
crates/cli/src/commands/local_db/sync/token.rs
Changed TokenPrepResult.tokens_prefix_sql from String to SqlStatementBatch. Updated initialization to use SqlStatementBatch::new(). Replaced generate_erc20_tokens_sql call with generate_erc20_token_statements.
CLI executor refactoring
crates/cli/src/commands/local_db/executor.rs
Added SqlStatementBatch import. Extended sqlvalue_to_rusqlite to handle SqlValue::U64 with overflow→Text conversion. Refactored execute_batch: enforces transaction wrapping, opens single connection, executes statements via invoke_statement helper, rolls back on error. Updated query_text/query_json to use new connection and statement helpers.
RainIndex/WASM executor
crates/common/src/raindex_client/local_db/executor.rs
Imported SqlStatementBatch; implemented execute_batch method for JsCallbackExecutor enforcing transaction wrapping and sequential statement execution with rollback on failure. Introduced invoke_statement helper for centralized JS callback handling. Updated tests to cover batch execution, rollback, and non-transaction error cases.

Sequence Diagram(s)

sequenceDiagram
    participant Sync as Sync Runner
    participant DataSource as SyncDataSource
    participant Exec as LocalDbQueryExecutor
    participant DB as SQLite DB

    rect rgb(200, 220, 255)
        note over Sync,DB: Old Flow: String-based SQL
        Sync->>DataSource: raw_events_to_sql()
        DataSource-->>Sync: String (SQL)
        Sync->>DataSource: events_to_sql(end_block, prefix_sql)
        DataSource-->>Sync: String (SQL)
        Sync->>Sync: Concatenate strings + update block
        Sync->>Exec: query_text(SqlStatement::new(sql))
        Exec->>DB: Execute single statement
        DB-->>Exec: Result
        Exec-->>Sync: Result
    end

    rect rgb(200, 255, 220)
        note over Sync,DB: New Flow: Batched Statements
        Sync->>DataSource: raw_events_to_statements()
        DataSource-->>Sync: SqlStatementBatch
        Sync->>DataSource: events_to_sql()
        DataSource-->>Sync: SqlStatementBatch
        Sync->>Sync: batch.extend() + batch.add(update_block)
        Sync->>Sync: batch.ensure_transaction()
        Sync->>Exec: execute_batch(&batch)
        rect rgb(240, 248, 255)
            Exec->>DB: BEGIN TRANSACTION
            Exec->>DB: Execute statement 1
            Exec->>DB: Execute statement 2
            Exec->>DB: ... (all statements)
            alt Success
                Exec->>DB: COMMIT
            else Failure
                Exec->>DB: ROLLBACK
            end
        end
        DB-->>Exec: Result
        Exec-->>Sync: Result
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • crates/common/src/local_db/query/sql_statement_batch.rs — New 200+ line module introducing SqlStatementBatch with transaction wrapping logic; verify ensure_transaction idempotence and transaction detection regex patterns
  • crates/common/src/local_db/insert.rs — Extensive refactoring replacing all string-based SQL generation with parameterized statements; verify SqlValue binding correctness across all event types and parameter placeholder sequencing
  • crates/cli/src/commands/local_db/executor.rs and crates/common/src/raindex_client/local_db/executor.rs — New execute_batch implementations with transaction enforcement and rollback logic; verify error handling, connection lifecycle, and statement-by-statement execution order
  • Trait signature changes across SyncDataSource, LocalDb, and LocalDbQueryExecutor — Verify all call sites and implementations have been updated consistently, especially parameter removal (end_block, prefix_sql)
  • CLI removal impact — Verify removed commands don't break any integration tests or downstream tooling that may depend on them

Possibly related issues

Possibly related PRs

Suggested reviewers

  • hardyjosh
  • 0xgleb

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The PR title "Refactor sql generation logic with SqlStatement" is partially related to the changeset but does not fully capture the primary changes. While the changeset does involve refactoring SQL generation logic, the main new type introduced is SqlStatementBatch (a container for grouping multiple SqlStatement instances), not SqlStatement itself. The title mentions the wrong type, which could mislead developers scanning the history. Additionally, the title omits other significant changes including the addition of the execute_batch functionality to the LocalDbQueryExecutor trait and the removal of multiple CLI commands that relied on the previous string-based SQL generation approach. A teammate reading this title would not fully understand the architectural shift to batch-based SQL execution. Consider revising the title to be more precise about the key deliverable. A better title might be "Introduce SqlStatementBatch for batched SQL execution" or "Refactor sql generation to use SqlStatementBatch" to accurately reflect that SqlStatementBatch is the primary new type being introduced, not SqlStatement. This would better communicate the architectural change and batch-based execution mechanism to developers reviewing the commit history.
Docstring Coverage ⚠️ Warning Docstring coverage is 47.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch local-db-stmt-refactor

Comment @coderabbitai help to get the list of available commands and usage tips.

@findolor
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 22, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@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: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
crates/common/src/local_db/decode.rs (1)

118-128: Minor: Redundant trim() call.

The validation logic correctly handles empty hex data by stripping the "0x"/"0X" prefix. However, line 123 calls .trim() on data_without_prefix, which is already derived from trimmed_data (line 118), making this second trim redundant.

Apply this diff to remove the redundant trim:

             let trimmed_data = event.data.trim();
             let data_without_prefix = trimmed_data
                 .strip_prefix("0x")
                 .or_else(|| trimmed_data.strip_prefix("0X"))
                 .unwrap_or(trimmed_data);
-            if data_without_prefix.trim().is_empty() {
+            if data_without_prefix.is_empty() {
                 return Err(DecodeError::MissingRequiredField {
crates/common/src/raindex_client/local_db/executor.rs (1)

17-56: Include SQL context in error messages

Add the SQL text to callback and Promise errors to aid debugging.

   async fn invoke_statement(&self, stmt: &SqlStatement) -> Result<String, LocalDbQueryError> {
@@
-    let result = self
+    let result = self
       .callback
       .call2(
         &JsValue::NULL,
-        &JsValue::from_str(&stmt.sql),
+        &JsValue::from_str(&stmt.sql),
         &js_params_val,
       )
       .map_err(|e| {
-        LocalDbQueryError::database(format!(
-          "JavaScript callback invocation failed: {:?}",
-          e
-        ))
+        LocalDbQueryError::database(format!(
+          "JavaScript callback invocation failed: {:?}; sql={}",
+          e,
+          stmt.sql
+        ))
       })?;
@@
-    let js_result = future.await.map_err(|e| {
-      LocalDbQueryError::database(format!("Promise resolution failed: {:?}", e))
-    })?;
+    let js_result = future.await.map_err(|e| {
+      LocalDbQueryError::database(format!(
+        "Promise resolution failed: {:?}; sql={}",
+        e,
+        stmt.sql
+      ))
+    })?;
crates/cli/src/commands/local_db/sync/runner/window.rs (1)

98-104: Avoid potential u64 overflow when bumping the start block

Use saturating_add to mirror the checked_add used earlier and avoid edge overflow.

 pub(super) fn default_start_block(last_synced_block: u64, deployment_block: u64) -> u64 {
   if last_synced_block == 0 {
     deployment_block
   } else {
-    last_synced_block + 1
+    last_synced_block.saturating_add(1)
   }
 }
crates/common/src/local_db/sync.rs (1)

71-78: Guard when already up to date (start_block > latest_block).

If last_synced_block == latest_block, start_block becomes latest+1 and BlockRange::inclusive() will error. Add an early return before constructing the range.

   let start_block = if last_synced_block == 0 {
       orderbook_cfg.deployment_block
   } else {
       last_synced_block.saturating_add(1)
   };

+  if start_block > latest_block {
+      status.send("Database already synced; no new blocks.".to_string())?;
+      return Ok(());
+  }
 
   let range = BlockRange::inclusive(start_block, latest_block)?;
crates/common/src/local_db/insert.rs (1)

145-150: Use structured logging instead of eprintln!.

Library code shouldn’t write to stderr directly. Prefer log::warn! so downstream can control sinks/levels.

-            eprintln!(
-                "Warning: Unknown event type for transaction {}: {}",
-                event.transaction_hash, decoded.note
-            );
+            log::warn!(
+                "Unknown event type for transaction {}: {}",
+                event.transaction_hash,
+                decoded.note
+            );
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d830600 and a60e31b.

📒 Files selected for processing (21)
  • crates/cli/src/commands/local_db/decode_events.rs (0 hunks)
  • crates/cli/src/commands/local_db/decoded_events_to_sql.rs (5 hunks)
  • crates/cli/src/commands/local_db/executor.rs (5 hunks)
  • crates/cli/src/commands/local_db/mod.rs (0 hunks)
  • crates/cli/src/commands/local_db/sync/data_source.rs (3 hunks)
  • crates/cli/src/commands/local_db/sync/runner/apply.rs (17 hunks)
  • crates/cli/src/commands/local_db/sync/runner/mod.rs (10 hunks)
  • crates/cli/src/commands/local_db/sync/runner/window.rs (2 hunks)
  • crates/cli/src/commands/local_db/sync/token.rs (3 hunks)
  • crates/cli/src/commands/local_db/tokens_fetch.rs (0 hunks)
  • crates/cli/src/commands/local_db/tokens_to_sql.rs (2 hunks)
  • crates/cli/src/lib.rs (1 hunks)
  • crates/common/src/local_db/decode.rs (2 hunks)
  • crates/common/src/local_db/insert.rs (37 hunks)
  • crates/common/src/local_db/mod.rs (4 hunks)
  • crates/common/src/local_db/query/executor.rs (2 hunks)
  • crates/common/src/local_db/query/mod.rs (1 hunks)
  • crates/common/src/local_db/query/sql_statement.rs (10 hunks)
  • crates/common/src/local_db/query/sql_statement_batch.rs (1 hunks)
  • crates/common/src/local_db/sync.rs (9 hunks)
  • crates/common/src/raindex_client/local_db/executor.rs (4 hunks)
💤 Files with no reviewable changes (3)
  • crates/cli/src/commands/local_db/decode_events.rs
  • crates/cli/src/commands/local_db/mod.rs
  • crates/cli/src/commands/local_db/tokens_fetch.rs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-06T14:41:41.909Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2159
File: crates/cli/src/commands/local_db/sync/runner/mod.rs:52-113
Timestamp: 2025-10-06T14:41:41.909Z
Learning: The local DB sync CLI command (crates/cli/src/commands/local_db/sync/) is designed for CI-only usage, and simple println! statements are preferred over structured logging for status messages.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/window.rs
  • crates/cli/src/lib.rs
  • crates/cli/src/commands/local_db/sync/data_source.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Deploy-Docs-Preview
  • GitHub Check: Deploy-Preview-Push
🔇 Additional comments (19)
crates/common/src/local_db/query/executor.rs (1)

3-3: LGTM: Clean trait extension for batch execution.

The addition of execute_batch to the LocalDbQueryExecutor trait is well-designed and consistent with the existing query methods. The signature appropriately uses &SqlStatementBatch and returns the same error type as other methods.

Also applies to: 12-13

crates/common/src/local_db/decode.rs (1)

904-917: LGTM: Comprehensive edge case coverage.

The test properly validates that both "0x" and "0X" prefixes are treated as missing data, ensuring the validation logic handles all hex prefix variations correctly.

crates/common/src/local_db/query/mod.rs (1)

15-15: LGTM: Clean public API extension.

The new module and re-exports properly expose the batch-based SQL types, maintaining consistency with the existing public API structure.

Also applies to: 20-20

crates/cli/src/commands/local_db/tokens_to_sql.rs (1)

74-105: LGTM: Correct batch materialization with proper placeholder handling.

The helper functions correctly convert the batch to a SQL string:

  • batch_to_string properly concatenates statements with line breaks
  • materialize_statement correctly iterates in reverse order (line 91) to avoid placeholder numbering conflicts (e.g., replacing ?1 before ?10)
  • render_sql_value provides appropriate SQL literal escaping for the use case

Note: This materialization is for generating static SQL files, not runtime parameterized queries, so the basic escaping is sufficient.

crates/cli/src/commands/local_db/executor.rs (3)

19-24: LGTM: Appropriate U64 handling for SQLite.

The conversion logic correctly handles SQLite's lack of unsigned 64-bit integers by attempting to convert to i64 first and falling back to text representation for values that don't fit. This ensures data fidelity while maintaining compatibility with SQLite's type system.


37-67: LGTM: Robust batch execution with proper transaction enforcement.

The implementation correctly:

  • Enforces transaction wrapping for batch safety (line 38-42)
  • Sets a busy timeout to handle concurrent access (lines 46-47)
  • Handles both parameterized and non-parameterized statements appropriately (lines 49-64)
  • Provides clear error context at each failure point

The requirement for transactions ensures atomicity of batch operations, which is essential for maintaining database consistency.


154-202: LGTM: Comprehensive test coverage.

The tests thoroughly validate:

  • Batch execution with mixed statement types (CREATE, INSERT, queries)
  • U64 parameter binding for both small and large values
  • Transaction requirement enforcement

This provides strong confidence in the batch execution functionality.

Also applies to: 337-401

crates/common/src/local_db/query/sql_statement.rs (3)

9-9: LGTM: U64 support with appropriate type handling.

The addition of the U64 variant and the From<u64> implementation (replacing TryFrom) simplifies the API by accepting all u64 values. The overflow handling is correctly deferred to the executor layer (which converts large values to text for SQLite compatibility).

Also applies to: 28-31


48-58: LGTM: Useful convenience constructor.

The new_with_params method provides a clean way to create statements with pre-populated parameters while maintaining proper placeholder numbering.


269-312: LGTM: Thorough test coverage for U64 support.

The tests comprehensively validate U64 handling across all relevant scenarios: direct push, bind_param_clause, bind_list_clause, and property-based testing. This ensures the U64 variant integrates correctly with all parameter binding mechanisms.

Also applies to: 346-353, 422-432, 569-581

crates/cli/src/lib.rs (1)

1-1: LGTM: Clean removal of obsolete CLI commands.

The removal of FetchEvents, DecodeEvents, DecodedEventsToSql, TokensFetch, and TokensToSql commands aligns with the PR's migration to batch-based SQL generation handled internally by the Sync command. The simplified enum maintains only the essential Dump and Sync operations.

Also applies to: 10-24

crates/cli/src/commands/local_db/sync/token.rs (1)

6-10: LGTM: Clean migration to batch-based token SQL generation.

The changes consistently migrate from string-based SQL to SqlStatementBatch, aligning with the broader refactoring. The type changes in TokenPrepResult and usage of generate_erc20_token_statements maintain the same functional behavior while enabling safer, parameterized SQL handling.

Also applies to: 18-18, 37-37, 68-68, 76-76

crates/cli/src/commands/local_db/decoded_events_to_sql.rs (1)

109-123: Minor: newline handling is fine; consider making batch_to_string private to the module

batch_to_string is already module‑private; no action needed. LGTM for legacy output formatting.

crates/cli/src/commands/local_db/sync/data_source.rs (1)

133-148: LGTM: trait now returns SqlStatementBatch and LocalDb impl delegates correctly

The interface aligns with the batch-based refactor; error mapping is consistent.

crates/cli/src/commands/local_db/sync/runner/mod.rs (1)

152-155: No changes required - prepare_sql already wraps batch via into_transaction()

The verification confirms that prepare_sql in crates/cli/src/commands/local_db/sync/runner/apply.rs correctly calls into_transaction() on line 106 before returning, with proper error handling. The batch will be transaction-wrapped when passed to execute_batch(), so no runtime error will occur.

crates/common/src/local_db/insert.rs (2)

156-237: LGTM: raw_events batching and deterministic ordering.

Sorted by (block_number, log_index), nullable timestamp handled via SqlValue::Null; all params bound. Looks solid.


865-907: No action required—schema correctly supports the ON CONFLICT clause.

The verification confirms the interpreter_store_sets table defines PRIMARY KEY (transaction_hash, log_index) (line 204 of query.sql), which provides the unique constraint the upsert needs. The ON CONFLICT clause in the code is correctly designed for this schema.

crates/common/src/local_db/mod.rs (1)

202-221: API transition to batched statements looks good.

Public surface now returns SqlStatementBatch with clear error mapping. No issues spotted.

crates/common/src/local_db/sync.rs (1)

51-55: No changes needed—the code already supports multi-statement SQL dumps.

The query_text() method at lines 74–77 of crates/cli/src/commands/local_db/executor.rs uses conn.execute_batch(stmt.sql()) for statements without parameters. Since download_and_decompress_dump() returns a plain SQL string with no parameters, this code path is taken, and execute_batch() correctly handles multi-statement SQL.

This is confirmed by existing tests: execute_and_query_round_trip and detects_required_tables both pass multi-statement SQL through query_text() successfully.

Comment thread crates/cli/src/commands/local_db/decoded_events_to_sql.rs Outdated
Comment on lines +101 to 108
tokens_prefix_sql.extend(data_source.events_to_sql(&decoded_events, &decimals_by_addr)?);
batch.extend(tokens_prefix_sql);
batch.add(build_update_last_synced_block_stmt(target_block));

batch
.into_transaction()
.map_err(|e| anyhow::anyhow!("Failed to wrap SQL in transaction: {}", e))
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Wrap only if needed to avoid AlreadyTransaction.

Prevent spurious failures when a data source returns a pre-wrapped batch.

-    batch
-        .into_transaction()
-        .map_err(|e| anyhow::anyhow!("Failed to wrap SQL in transaction: {}", e))
+    (if batch.is_transaction() {
+        Ok(batch)
+    } else {
+        batch.into_transaction()
+    })
+    .map_err(|e| anyhow::anyhow!("Failed to wrap SQL in transaction: {}", e))

If you adopt SqlStatementBatch::ensure_transaction(), this becomes:

-    batch.into_transaction()
+    batch.ensure_transaction()

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In crates/cli/src/commands/local_db/sync/runner/apply.rs around lines 101 to
108, the code always calls into_transaction() which fails when the data source
already returned a transaction-wrapped batch; change this to use
SqlStatementBatch::ensure_transaction() (or implement it if missing) so the
batch is wrapped only when necessary, and keep the same map_err(...) error
handling to surface failures from ensuring a transaction.

Comment thread crates/common/src/local_db/mod.rs Outdated
Comment thread crates/common/src/local_db/query/sql_statement_batch.rs Outdated
Comment thread crates/common/src/local_db/sync.rs Outdated
Comment on lines +369 to +374
async fn execute_batch(&self, batch: &SqlStatementBatch) -> Result<(), LocalDbQueryError> {
for stmt in batch {
let _ = self.query_text(stmt).await?;
}
Ok(())
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Test executor: ignore BEGIN/COMMIT to avoid brittle failures.

MockDb currently forwards all statements to query_text; transactional sentinels will fail unless mapped. Skip them in tests.

-        async fn execute_batch(&self, batch: &SqlStatementBatch) -> Result<(), LocalDbQueryError> {
-            for stmt in batch {
-                let _ = self.query_text(stmt).await?;
-            }
-            Ok(())
-        }
+        async fn execute_batch(&self, batch: &SqlStatementBatch) -> Result<(), LocalDbQueryError> {
+            for stmt in batch {
+                let sql = stmt.sql().trim();
+                if sql.eq_ignore_ascii_case("BEGIN TRANSACTION")
+                    || sql.eq_ignore_ascii_case("COMMIT") {
+                    continue;
+                }
+                let _ = self.query_text(stmt).await?;
+            }
+            Ok(())
+        }
📝 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 execute_batch(&self, batch: &SqlStatementBatch) -> Result<(), LocalDbQueryError> {
for stmt in batch {
let _ = self.query_text(stmt).await?;
}
Ok(())
}
async fn execute_batch(&self, batch: &SqlStatementBatch) -> Result<(), LocalDbQueryError> {
for stmt in batch {
let sql = stmt.sql().trim();
if sql.eq_ignore_ascii_case("BEGIN TRANSACTION")
|| sql.eq_ignore_ascii_case("COMMIT") {
continue;
}
let _ = self.query_text(stmt).await?;
}
Ok(())
}
🤖 Prompt for AI Agents
In crates/common/src/local_db/sync.rs around lines 369 to 374, the test executor
currently forwards all statements including transactional sentinels to
query_text which makes tests brittle; update execute_batch to skip statements
that are transactional sentinels (e.g., "BEGIN", "BEGIN;", "COMMIT", "COMMIT;")
by trimming whitespace and trailing semicolons and doing a case-insensitive
match, only calling query_text for non-sentinel statements and returning Ok(())
after the loop.

Comment thread crates/common/src/raindex_client/local_db/executor.rs
@findolor findolor linked an issue Oct 23, 2025 that may be closed by this pull request
Base automatically changed from local-db-decode-set-abi to main October 31, 2025 06:07
Copy link
Copy Markdown
Contributor

@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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a60e31b and a480411.

📒 Files selected for processing (13)
  • crates/cli/src/commands/local_db/decoded_events_to_sql.rs (0 hunks)
  • crates/cli/src/commands/local_db/executor.rs (5 hunks)
  • crates/cli/src/commands/local_db/fetch_events.rs (0 hunks)
  • crates/cli/src/commands/local_db/sync/data_source.rs (3 hunks)
  • crates/cli/src/commands/local_db/sync/runner/apply.rs (17 hunks)
  • crates/cli/src/commands/local_db/sync/runner/mod.rs (10 hunks)
  • crates/cli/src/commands/local_db/tokens_to_sql.rs (0 hunks)
  • crates/common/src/local_db/insert.rs (37 hunks)
  • crates/common/src/local_db/mod.rs (4 hunks)
  • crates/common/src/local_db/query/mod.rs (1 hunks)
  • crates/common/src/local_db/query/sql_statement_batch.rs (1 hunks)
  • crates/common/src/local_db/sync.rs (9 hunks)
  • crates/common/src/raindex_client/local_db/executor.rs (5 hunks)
💤 Files with no reviewable changes (3)
  • crates/cli/src/commands/local_db/decoded_events_to_sql.rs
  • crates/cli/src/commands/local_db/fetch_events.rs
  • crates/cli/src/commands/local_db/tokens_to_sql.rs
🧰 Additional context used
📓 Path-based instructions (3)
crates/*/{src,tests,benches,examples}/**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Rust code must pass clippy with all warnings denied (cargo clippy --workspace --all-targets --all-features -D warnings)

Files:

  • crates/common/src/local_db/query/mod.rs
  • crates/cli/src/commands/local_db/sync/runner/mod.rs
  • crates/cli/src/commands/local_db/executor.rs
  • crates/common/src/raindex_client/local_db/executor.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
  • crates/cli/src/commands/local_db/sync/data_source.rs
  • crates/common/src/local_db/query/sql_statement_batch.rs
  • crates/common/src/local_db/sync.rs
  • crates/common/src/local_db/insert.rs
  • crates/common/src/local_db/mod.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Rust code lives in the workspace under crates/* (e.g., cli, common, bindings, js_api, quote, subgraph, settings, math, integration_tests)

Files:

  • crates/common/src/local_db/query/mod.rs
  • crates/cli/src/commands/local_db/sync/runner/mod.rs
  • crates/cli/src/commands/local_db/executor.rs
  • crates/common/src/raindex_client/local_db/executor.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
  • crates/cli/src/commands/local_db/sync/data_source.rs
  • crates/common/src/local_db/query/sql_statement_batch.rs
  • crates/common/src/local_db/sync.rs
  • crates/common/src/local_db/insert.rs
  • crates/common/src/local_db/mod.rs
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Format Rust with nix develop -c cargo fmt --all
Lint Rust with nix develop -c rainix-rs-static (preconfigured flags)
Use snake_case for Rust crates/modules and PascalCase for types

Files:

  • crates/common/src/local_db/query/mod.rs
  • crates/cli/src/commands/local_db/sync/runner/mod.rs
  • crates/cli/src/commands/local_db/executor.rs
  • crates/common/src/raindex_client/local_db/executor.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
  • crates/cli/src/commands/local_db/sync/data_source.rs
  • crates/common/src/local_db/query/sql_statement_batch.rs
  • crates/common/src/local_db/sync.rs
  • crates/common/src/local_db/insert.rs
  • crates/common/src/local_db/mod.rs
🧠 Learnings (33)
📓 Common learnings
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:25:47.873Z
Learning: After each new commit review for rainlanguage/rain.orderbook repository, generate a PR size report in a separate comment with the format: "TOTAL=number ADDITIONS=number DELETIONS=number". This report should exclude irrelevant files such as lock files (e.g., package-lock.json, cargo.lock).
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2145
File: crates/common/src/raindex_client/local_db/query/create_tables/query.sql:71-72
Timestamp: 2025-10-06T11:44:07.888Z
Learning: The local DB feature in the rain.orderbook codebase is not live yet (as of PR #2145), so schema migrations for existing databases are not required when modifying table structures in `crates/common/src/raindex_client/local_db/query/create_tables/query.sql`.
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:25:47.873Z
Learning: After each new commit review for rainlanguage/rain.orderbook repository, generate a PR size report in a separate comment with the exact format: "TOTAL=number\nADDITIONS=number\nDELETIONS=number". This report should exclude irrelevant files such as lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:26:31.566Z
Learning: For PR #1884 and future PRs in rainlanguage/rain.orderbook repository, provide PR size reports in a separate comment with ONLY the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number", without any additional text or explanation. Reports should exclude irrelevant files such as lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2117
File: crates/js_api/src/gui/select_tokens.rs:421-424
Timestamp: 2025-09-02T08:04:34.729Z
Learning: User findolor in the rainlanguage/rain.orderbook codebase prefers not to change test code when tests are already passing, even if there appear to be type mismatches or potential issues. Working tests should be left alone unless there are actual errors.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1956
File: crates/common/src/fuzz/mod.rs:64-64
Timestamp: 2025-07-04T09:02:57.301Z
Learning: In rainlanguage/rain.orderbook, user findolor prefers to limit type consistency changes to only the parts directly related to the current work scope. For example, when updating chain_id fields from u64 to u32 in fuzz-related code, unrelated files like tauri-app wallet commands can remain as u64 if they serve different purposes and aren't part of the current changes.
📚 Learning: 2025-10-06T14:41:41.909Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2159
File: crates/cli/src/commands/local_db/sync/runner/mod.rs:52-113
Timestamp: 2025-10-06T14:41:41.909Z
Learning: The local DB sync CLI command (crates/cli/src/commands/local_db/sync/) is designed for CI-only usage, and simple println! statements are preferred over structured logging for status messages.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
  • crates/cli/src/commands/local_db/sync/data_source.rs
  • crates/common/src/local_db/sync.rs
  • crates/common/src/local_db/mod.rs
📚 Learning: 2025-10-06T14:39:36.425Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2159
File: crates/cli/src/commands/local_db/sync/cli.rs:37-78
Timestamp: 2025-10-06T14:39:36.425Z
Learning: In the SyncLocalDb CLI command (crates/cli/src/commands/local_db/sync/cli.rs), block range validation (e.g., start_block <= end_block) is handled internally by the sync runner, not at the CLI entry point.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
  • crates/cli/src/commands/local_db/sync/data_source.rs
📚 Learning: 2025-10-06T11:44:07.888Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2145
File: crates/common/src/raindex_client/local_db/query/create_tables/query.sql:71-72
Timestamp: 2025-10-06T11:44:07.888Z
Learning: The local DB feature in the rain.orderbook codebase is not live yet (as of PR #2145), so schema migrations for existing databases are not required when modifying table structures in `crates/common/src/raindex_client/local_db/query/create_tables/query.sql`.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
  • crates/cli/src/commands/local_db/executor.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
  • crates/cli/src/commands/local_db/sync/data_source.rs
  • crates/common/src/local_db/mod.rs
📚 Learning: 2025-10-14T07:51:55.148Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2202
File: crates/common/src/raindex_client/local_db/sync.rs:33-34
Timestamp: 2025-10-14T07:51:55.148Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the hard-coded `DEFAULT_SYNC_CHAIN_ID` constant (set to `SUPPORTED_LOCAL_DB_CHAINS[0]`) will be replaced with proper chain ID handling in downstream PRs as part of the multi-network/orderbook implementation.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
  • crates/cli/src/commands/local_db/sync/data_source.rs
📚 Learning: 2025-10-18T10:38:41.273Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2237
File: crates/common/src/raindex_client/local_db/sync.rs:79-89
Timestamp: 2025-10-18T10:38:41.273Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the sync_database method currently only supports indexing a single orderbook per chain ID, which is why `.first()` is used to select the orderbook configuration. Multi-orderbook support per chain ID is planned for future PRs.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
  • crates/cli/src/commands/local_db/executor.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
  • crates/common/src/local_db/sync.rs
📚 Learning: 2025-10-06T14:13:18.531Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2155
File: crates/common/src/raindex_client/trades.rs:133-152
Timestamp: 2025-10-06T14:13:18.531Z
Learning: In the rain.orderbook codebase, the `page` parameter in `RaindexOrder::get_trades_list` method (in crates/common/src/raindex_client/trades.rs) is kept for backwards compatibility with subgraph logic, but the LocalDb fast-path intentionally returns all trades without implementing pagination.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
📚 Learning: 2025-06-17T16:32:04.554Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1903
File: crates/js_api/src/gui/order_operations.rs:124-134
Timestamp: 2025-06-17T16:32:04.554Z
Learning: In the rain.orderbook codebase, RPC lists are typically small (2 items maximum), so performance optimizations around cloning and converting small Vec<Url> collections are generally unnecessary.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
📚 Learning: 2025-07-15T08:01:38.534Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1994
File: crates/common/src/raindex_client/vaults.rs:282-292
Timestamp: 2025-07-15T08:01:38.534Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor prefers to avoid concurrency optimizations like using `futures::future::try_join_all` for parallel processing of balance changes, considering such optimizations "not that critical at the moment" when the performance impact is minimal.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
📚 Learning: 2025-08-26T14:52:37.000Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2099
File: crates/common/src/hyper_rpc.rs:3-7
Timestamp: 2025-08-26T14:52:37.000Z
Learning: In the rain.orderbook codebase, creating new reqwest::Client instances per request in HyperRpcClient is not considered an issue by the maintainers, despite potential performance benefits of client reuse.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
📚 Learning: 2025-07-23T10:51:12.278Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2012
File: crates/js_api/src/registry.rs:233-252
Timestamp: 2025-07-23T10:51:12.278Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor considers the pattern of creating a partially initialized struct instance within a constructor and then populating it through async operations to be acceptable, as long as the partial state is never exposed to users and the constructor returns Result<T, E> with proper error propagation using the ? operator.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
📚 Learning: 2025-10-13T12:57:05.900Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2198
File: crates/common/src/raindex_client/local_db/query/fetch_store_addresses/mod.rs:7-8
Timestamp: 2025-10-13T12:57:05.900Z
Learning: In the rain.orderbook repository, using unqualified serde helper names (e.g., `#[serde(with = "serde_address")]`) that rely on glob imports is acceptable and does not need to be changed to fully qualified paths.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
📚 Learning: 2025-10-02T19:17:20.332Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2163
File: crates/common/src/raindex_client/orders.rs:738-741
Timestamp: 2025-10-02T19:17:20.332Z
Learning: In crates/common/src/raindex_client/orders.rs, fetch_dotrain_source() is intentionally called in try_from_sg_order for every order conversion because the dotrain source information is needed immediately. A future optimization with local DB logic is planned to eliminate the network round-trip concern.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
📚 Learning: 2025-10-06T11:13:29.956Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2123
File: crates/common/src/raindex_client/local_db/mod.rs:23-29
Timestamp: 2025-10-06T11:13:29.956Z
Learning: In `crates/common/src/raindex_client/local_db/mod.rs`, the `Default` implementation for `LocalDb` that creates an RPC client pointing to `http://localhost:4444` is acceptable because the RPC client must be explicitly configured before actual usage in production scenarios.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/mod.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
📚 Learning: 2025-05-17T15:32:28.733Z
Learnt from: 0xgleb
Repo: rainlanguage/rain.orderbook PR: 1790
File: tauri-app/src-tauri/src/commands/vault.rs:67-67
Timestamp: 2025-05-17T15:32:28.733Z
Learning: For the PR focused on testing Tauri commands::order module, the generic type parameter R: Runtime was selectively added where needed for the PR scope, applying the changes primarily to order.rs and related files while leaving other modules like vault.rs for potential future refactoring.

Applied to files:

  • crates/cli/src/commands/local_db/executor.rs
📚 Learning: 2025-10-21T05:15:50.518Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2256
File: crates/common/src/raindex_client/local_db/query/fetch_tables.rs:7-7
Timestamp: 2025-10-21T05:15:50.518Z
Learning: In Rust 2021+ editions, passing a reference to a temporary into an async function within the same expression (e.g., `exec.query_json(&fetch_tables_stmt()).await`) is safe and idiomatic. The temporary lifetime is extended across the await point, so this pattern should not be flagged as an issue.

Applied to files:

  • crates/cli/src/commands/local_db/executor.rs
  • crates/common/src/raindex_client/local_db/executor.rs
  • crates/common/src/local_db/sync.rs
📚 Learning: 2025-10-06T14:12:05.824Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2155
File: crates/common/src/raindex_client/local_db/query/fetch_order_trades/query.sql:86-108
Timestamp: 2025-10-06T14:12:05.824Z
Learning: CTEs (Common Table Expressions) are not supported in the local DB SQL implementation used in the rain.orderbook codebase.

Applied to files:

  • crates/cli/src/commands/local_db/executor.rs
  • crates/cli/src/commands/local_db/sync/runner/apply.rs
📚 Learning: 2025-05-19T13:40:56.080Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1858
File: crates/subgraph/src/orderbook_client/mod.rs:54-58
Timestamp: 2025-05-19T13:40:56.080Z
Learning: The `wasm_bindgen_utils` crate in the Rain Orderbook project handles conditional compilation for `JsValue` and `JsError` internally, allowing `impl From<Error> for JsValue` to work on non-WASM targets without explicit cfg guards.

Applied to files:

  • crates/common/src/raindex_client/local_db/executor.rs
📚 Learning: 2025-05-14T05:51:50.277Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1715
File: crates/js_api/src/common/mod.rs:55-59
Timestamp: 2025-05-14T05:51:50.277Z
Learning: In the Rain Orderbook project, the error handling for WASM exported functions uses WasmEncodedError which includes both the original error message and a human-readable version, making direct modification of the JsValue conversion unnecessary.

Applied to files:

  • crates/common/src/raindex_client/local_db/executor.rs
📚 Learning: 2025-04-30T09:28:36.960Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1715
File: crates/js_api/src/common/mod.rs:111-118
Timestamp: 2025-04-30T09:28:36.960Z
Learning: In the rain.orderbook repository, the WASM tests are already properly configured with conditional compilation using `#[cfg(target_family = "wasm")]` and `#[cfg(not(target_family = "wasm"))]`, and don't require additional `wasm_bindgen_test_configure!(run_in_browser)` directives.

Applied to files:

  • crates/common/src/raindex_client/local_db/executor.rs
  • crates/common/src/local_db/sync.rs
📚 Learning: 2025-10-19T15:52:58.239Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2245
File: crates/common/src/raindex_client/local_db/executor.rs:17-46
Timestamp: 2025-10-19T15:52:58.239Z
Learning: When formatting JsValue errors in Rust wasm code using `{:?}`, the Debug output is sufficiently informative and does not produce unhelpful "[object Object]" strings in practice.

Applied to files:

  • crates/common/src/raindex_client/local_db/executor.rs
📚 Learning: 2025-05-27T06:16:12.195Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1874
File: tauri-app/src-tauri/src/transaction_status.rs:87-114
Timestamp: 2025-05-27T06:16:12.195Z
Learning: In tauri-app/src-tauri/src/transaction_status.rs, testing one WriteTransactionStatus variant (like PendingPrepare) is sufficient for the update_status_and_emit method since all variants follow the same code path through the From<WriteTransactionStatus<T>> implementation.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/apply.rs
  • crates/common/src/local_db/query/sql_statement_batch.rs
  • crates/common/src/local_db/sync.rs
  • crates/common/src/local_db/insert.rs
📚 Learning: 2025-05-27T06:16:35.738Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1874
File: tauri-app/src-tauri/src/transaction_status.rs:69-127
Timestamp: 2025-05-27T06:16:35.738Z
Learning: In tauri-app/src-tauri/src/transaction_status.rs, directly accessing internal RwLock state in tests using `notice.0.read().unwrap()` is acceptable and does not require encapsulation through public getter methods.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/apply.rs
  • crates/common/src/local_db/sync.rs
📚 Learning: 2025-10-06T13:03:35.337Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2146
File: crates/cli/src/commands/local_db/README.md:22-106
Timestamp: 2025-10-06T13:03:35.337Z
Learning: In the rain.orderbook repository, `cargo run` commands work without the `--` separator (e.g., `cargo run local-db fetch-events` works directly). Do not suggest adding `--` before CLI arguments in cargo run examples for this repository.

Applied to files:

  • crates/cli/src/commands/local_db/sync/runner/apply.rs
📚 Learning: 2025-05-20T10:20:08.206Z
Learnt from: 0xgleb
Repo: rainlanguage/rain.orderbook PR: 1859
File: crates/quote/src/quote_debug.rs:472-492
Timestamp: 2025-05-20T10:20:08.206Z
Learning: In the Rain Orderbook codebase, the `#[tokio::test(flavor = "multi_thread")]` annotation is specifically needed for tests that use `LocalEvm`, not just for consistency across all async tests.

Applied to files:

  • crates/common/src/local_db/sync.rs
  • crates/common/src/local_db/insert.rs
📚 Learning: 2025-07-18T10:31:05.498Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2008
File: crates/common/src/raindex_client/add_orders.rs:85-86
Timestamp: 2025-07-18T10:31:05.498Z
Learning: In the rainlanguage/rain.orderbook codebase, cfg-guarded imports like `#[cfg(not(target_family = "wasm"))] use super::*;` in test modules are sometimes needed to fix compiler warnings, even when similar imports exist in nested sub-modules. These should not be removed as they serve a specific purpose in the compilation process.

Applied to files:

  • crates/common/src/local_db/sync.rs
📚 Learning: 2025-05-14T05:13:59.713Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1744
File: crates/subgraph/src/orderbook_client.rs:44-46
Timestamp: 2025-05-14T05:13:59.713Z
Learning: In the rain.orderbook project, WASM dependencies are intentionally made available in non-WASM targets to facilitate testing of WASM-related functionality, so conditional compilation guards like `#[cfg(target_family = "wasm")]` should not be added to imports or implementations that may be needed for tests.

Applied to files:

  • crates/common/src/local_db/sync.rs
📚 Learning: 2025-08-02T02:34:32.237Z
Learnt from: brusherru
Repo: rainlanguage/rain.orderbook PR: 2036
File: crates/js_api/src/filters/raindex_filter_store.rs:446-533
Timestamp: 2025-08-02T02:34:32.237Z
Learning: In the rainlanguage/rain.orderbook project's RaindexFilterStore WASM tests (crates/js_api/src/filters/raindex_filter_store.rs), brusherru decided to focus on testing only methods without side effects (that don't use web_sys) due to difficulties with mocking localStorage and window APIs in the WASM test environment. This pragmatic approach tests pure logic separately from browser integration.

Applied to files:

  • crates/common/src/local_db/sync.rs
📚 Learning: 2025-07-31T19:34:11.716Z
Learnt from: brusherru
Repo: rainlanguage/rain.orderbook PR: 2044
File: crates/common/src/raindex_client/vaults_list.rs:363-423
Timestamp: 2025-07-31T19:34:11.716Z
Learning: In the rainlanguage/rain.orderbook project, for WASM-exposed functionality like VaultsList, the team prefers to keep comprehensive tests in the non-WASM environment due to the complexity of recreating objects like RaindexVaults in WASM. WASM tests focus on basic functionality and error cases since the WASM code reuses the already-tested non-WASM implementation.

Applied to files:

  • crates/common/src/local_db/sync.rs
📚 Learning: 2025-05-16T17:24:34.724Z
Learnt from: 0xgleb
Repo: rainlanguage/rain.orderbook PR: 1844
File: tauri-app/src-tauri/src/commands/wallet.rs:27-28
Timestamp: 2025-05-16T17:24:34.724Z
Learning: In Rust projects, dependencies listed in the [dependencies] section of Cargo.toml are available for both application code and tests. The tokio crate with the "full" feature set includes the "test" feature needed for `#[tokio::test]` to work properly.

Applied to files:

  • crates/common/src/local_db/sync.rs
📚 Learning: 2025-10-06T13:09:36.912Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2146
File: crates/common/src/raindex_client/local_db/insert.rs:166-195
Timestamp: 2025-10-06T13:09:36.912Z
Learning: In the rainlanguage/rain.orderbook codebase, manual SQL string construction with apostrophe escaping (replacing single quotes with double single quotes) is acceptable for inserting token metadata into SQLite, as it meets the security requirements for their use case.

Applied to files:

  • crates/common/src/local_db/insert.rs
📚 Learning: 2025-09-30T21:18:01.636Z
Learnt from: hardyjosh
Repo: rainlanguage/rain.orderbook PR: 2167
File: crates/virtual-raindex/src/engine/take.rs:131-138
Timestamp: 2025-09-30T21:18:01.636Z
Learning: In the virtual-raindex take order flow (crates/virtual-raindex/src/engine/take.rs), balance diffs are written from the order's perspective where the taker is the counterparty: the order's input column receives taker_output (what the taker provides to the order) and the order's output column receives taker_input (what the taker requests from the order).

Applied to files:

  • crates/common/src/local_db/insert.rs
📚 Learning: 2025-10-10T05:16:12.250Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2186
File: crates/common/src/raindex_client/local_db/query/update_last_synced_block/query.sql:4-5
Timestamp: 2025-10-10T05:16:12.250Z
Learning: In the rain.orderbook codebase, SQL templates use string replacement rather than parameterized queries. Placeholders that represent string values (like `?orderbook_address`) should remain quoted in the SQL template (e.g., `'?orderbook_address'`) because the implementation escapes and replaces these placeholders directly, resulting in properly quoted SQL values after replacement.

Applied to files:

  • crates/common/src/local_db/insert.rs
🧬 Code graph analysis (10)
crates/common/src/local_db/query/mod.rs (1)
crates/common/src/raindex_client/local_db/query/update_last_synced_block.rs (1)
  • update_last_synced_block (4-10)
crates/cli/src/commands/local_db/sync/runner/mod.rs (4)
crates/cli/src/commands/local_db/sync/runner/apply.rs (2)
  • prepare_sql (62-106)
  • raw_events_to_statements (210-216)
crates/common/src/local_db/query/sql_statement_batch.rs (1)
  • statements (61-63)
crates/cli/src/commands/local_db/sync/data_source.rs (2)
  • raw_events_to_statements (42-45)
  • raw_events_to_statements (144-150)
crates/common/src/local_db/insert.rs (2)
  • raw_events_to_statements (156-237)
  • raw_events (168-191)
crates/cli/src/commands/local_db/executor.rs (3)
crates/common/src/local_db/sync.rs (5)
  • serde_json (392-392)
  • execute_batch (374-379)
  • query_text (396-405)
  • new (351-357)
  • query_json (381-394)
crates/common/src/local_db/query/sql_statement.rs (7)
  • params (64-66)
  • new (41-46)
  • new (181-185)
  • from (14-16)
  • from (19-21)
  • from (24-26)
  • from (29-31)
crates/common/src/local_db/query/executor.rs (3)
  • execute_batch (12-12)
  • query_text (18-18)
  • query_json (14-16)
crates/common/src/raindex_client/local_db/executor.rs (5)
crates/cli/src/commands/local_db/executor.rs (4)
  • invoke_statement (42-57)
  • execute_batch (62-79)
  • new (28-32)
  • query_text (81-85)
crates/common/src/local_db/sync.rs (3)
  • execute_batch (374-379)
  • new (351-357)
  • query_text (396-405)
crates/common/src/local_db/query/executor.rs (2)
  • execute_batch (12-12)
  • query_text (18-18)
crates/common/src/local_db/query/sql_statement_batch.rs (3)
  • new (12-14)
  • len (65-67)
  • from (79-81)
crates/common/src/local_db/query/sql_statement.rs (8)
  • new (41-46)
  • new (181-185)
  • sql (60-62)
  • params (64-66)
  • from (14-16)
  • from (19-21)
  • from (24-26)
  • from (29-31)
crates/cli/src/commands/local_db/sync/runner/apply.rs (5)
crates/common/src/local_db/query/update_last_synced_block/mod.rs (1)
  • build_update_last_synced_block_stmt (5-10)
crates/cli/src/commands/local_db/sync/token.rs (1)
  • prepare_token_metadata (22-85)
crates/common/src/local_db/insert.rs (2)
  • raw_events (168-191)
  • raw_events_to_statements (156-237)
crates/common/src/local_db/query/sql_statement_batch.rs (5)
  • statements (61-63)
  • new (12-14)
  • from (79-81)
  • is_empty (69-71)
  • len (65-67)
crates/cli/src/commands/local_db/sync/data_source.rs (2)
  • raw_events_to_statements (42-45)
  • raw_events_to_statements (144-150)
crates/cli/src/commands/local_db/sync/data_source.rs (5)
crates/common/src/local_db/mod.rs (2)
  • raw_events_to_statements (249-256)
  • decoded_events_to_statements (237-247)
crates/cli/src/commands/local_db/sync/runner/apply.rs (1)
  • raw_events_to_statements (210-216)
crates/common/src/local_db/insert.rs (3)
  • raw_events_to_statements (156-237)
  • raw_events (168-191)
  • decoded_events_to_statements (95-154)
crates/cli/src/commands/local_db/sync/runner/mod.rs (1)
  • raw_events_to_statements (329-335)
crates/cli/src/commands/local_db/sync/runner/window.rs (1)
  • raw_events_to_statements (191-193)
crates/common/src/local_db/query/sql_statement_batch.rs (1)
crates/common/src/local_db/query/sql_statement.rs (1)
  • sql (60-62)
crates/common/src/local_db/sync.rs (5)
crates/cli/src/commands/local_db/executor.rs (2)
  • new (28-32)
  • execute_batch (62-79)
crates/common/src/local_db/query/sql_statement_batch.rs (3)
  • new (12-14)
  • statements (61-63)
  • len (65-67)
crates/common/src/raindex_client/local_db/executor.rs (2)
  • new (13-15)
  • execute_batch (61-76)
crates/common/src/local_db/query/update_last_synced_block/mod.rs (1)
  • build_update_last_synced_block_stmt (5-10)
crates/common/src/local_db/insert.rs (1)
  • generate_erc20_token_statements (240-274)
crates/common/src/local_db/insert.rs (4)
crates/common/src/local_db/mod.rs (3)
  • decoded_events_to_statements (237-247)
  • new (205-207)
  • raw_events_to_statements (249-256)
crates/common/src/local_db/query/sql_statement_batch.rs (3)
  • new (12-14)
  • len (65-67)
  • statements (61-63)
crates/common/src/local_db/query/sql_statement.rs (2)
  • new_with_params (48-58)
  • sql (60-62)
crates/common/src/local_db/tokens.rs (1)
  • build_event (74-83)
crates/common/src/local_db/mod.rs (5)
crates/common/src/local_db/insert.rs (3)
  • decoded_events_to_statements (95-154)
  • raw_events_to_statements (156-237)
  • raw_events (168-191)
crates/cli/src/commands/local_db/sync/data_source.rs (2)
  • raw_events_to_statements (42-45)
  • raw_events_to_statements (144-150)
crates/cli/src/commands/local_db/sync/runner/apply.rs (1)
  • raw_events_to_statements (210-216)
crates/cli/src/commands/local_db/sync/runner/mod.rs (1)
  • raw_events_to_statements (329-335)
crates/cli/src/commands/local_db/sync/runner/window.rs (1)
  • raw_events_to_statements (191-193)

Comment on lines +81 to 85
async fn query_text(&self, stmt: &SqlStatement) -> Result<String, LocalDbQueryError> {
let conn = self.open_connection()?;
Self::invoke_statement(&conn, stmt)?;
Ok(String::new())
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Restore row-returning behaviour for query_text

query_text now just runs invoke_statement, which in turn calls Connection::execute_batch/Statement::execute and drops the payload. That breaks every caller that issues a SELECT via this path: execute_batch errors as soon as the SQL produces rows, and even if it didn’t, we’d still hand back an empty String. The trait contract promises textual data (the JS executor still delivers it), and CLI commands like the dump/query helpers rely on it. Please reinstate the previous logic—prepare the statement, read the result set, and build the text (or delegate to the query_json implementation and stringify)—instead of using the non-row API here.

🤖 Prompt for AI Agents
In crates/cli/src/commands/local_db/executor.rs around lines 81 to 85,
query_text currently calls invoke_statement which uses execute_batch/execute and
drops any row payloads, returning an empty String and breaking SELECT callers;
restore the previous row-returning behavior by preparing the statement on the
opened connection, executing it as a query, iterating the result rows to build a
textual representation (or call the existing query_json to get JSON and
stringify it) and return that text, instead of using
invoke_statement/execute_batch; ensure errors are propagated as
LocalDbQueryError and resources (statement/result) are properly closed.

Comment on lines +37 to +53
/// Wrap the batch in a transaction when needed; no-op if already wrapped.
pub fn ensure_transaction(mut self) -> Self {
if self
.statements
.first()
.is_some_and(|stmt| is_begin(stmt.sql()))
|| self
.statements
.last()
.is_some_and(|stmt| is_commit(stmt.sql()))
{
return self;
}

self.wrap_with_transaction();
self
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

ensure_transaction drops COMMIT after extend
ensure_transaction bails out as soon as either the first or last statement looks transactional. If we extend a pre-wrapped batch (e.g., prep.tokens_prefix_sql) with more statements, the leading BEGIN TRANSACTION survives but its matching COMMIT is now in the middle of the batch. Because of the early return, we never append a new closing COMMIT, so batch.is_transaction() stays false and downstream executors (see LocalDbQueryExecutor::execute_batch) reject the batch at runtime. This regresses legitimate workflows that mix already-wrapped fragments with additional statements. Please make sure we only short-circuit when both boundaries are present and strip stray sentinels before wrapping to avoid nested BEGINs. For example:

-        if self
-            .statements
-            .first()
-            .is_some_and(|stmt| is_begin(stmt.sql()))
-            || self
-                .statements
-                .last()
-                .is_some_and(|stmt| is_commit(stmt.sql()))
-        {
-            return self;
-        }
-
-        self.wrap_with_transaction();
+        let has_begin = self
+            .statements
+            .first()
+            .is_some_and(|stmt| is_begin(stmt.sql()));
+        let has_commit = self
+            .statements
+            .last()
+            .is_some_and(|stmt| is_commit(stmt.sql()));
+
+        if has_begin && has_commit {
+            return self;
+        }
+
+        if has_begin {
+            let _ = self.statements.remove(0);
+        }
+        if has_commit {
+            let _ = self.statements.pop();
+        }
+        self.wrap_with_transaction();
📝 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
/// Wrap the batch in a transaction when needed; no-op if already wrapped.
pub fn ensure_transaction(mut self) -> Self {
if self
.statements
.first()
.is_some_and(|stmt| is_begin(stmt.sql()))
|| self
.statements
.last()
.is_some_and(|stmt| is_commit(stmt.sql()))
{
return self;
}
self.wrap_with_transaction();
self
}
/// Wrap the batch in a transaction when needed; no-op if already wrapped.
pub fn ensure_transaction(mut self) -> Self {
let has_begin = self
.statements
.first()
.is_some_and(|stmt| is_begin(stmt.sql()));
let has_commit = self
.statements
.last()
.is_some_and(|stmt| is_commit(stmt.sql()));
if has_begin && has_commit {
return self;
}
if has_begin {
let _ = self.statements.remove(0);
}
if has_commit {
let _ = self.statements.pop();
}
self.wrap_with_transaction();
self
}
🤖 Prompt for AI Agents
In crates/common/src/local_db/query/sql_statement_batch.rs around lines 37–53,
the current early return checks only first OR last transactional sentinel and
can drop a COMMIT when extending a pre-wrapped fragment; change the logic to
only short-circuit when BOTH a leading BEGIN and a trailing COMMIT are present,
and otherwise do not return early — instead strip any stray sentinels (remove a
leading BEGIN if present, remove a trailing COMMIT if present) to avoid nested
BEGINs, then call wrap_with_transaction() and return the batch.

@findolor findolor merged commit 07c9229 into main Oct 31, 2025
19 checks passed
@findolor findolor deleted the local-db-stmt-refactor branch October 31, 2025 09:23
@github-actions
Copy link
Copy Markdown
Contributor

@coderabbitai assess this PR size classification for the totality of the PR with the following criterias and report it in your comment:

S/M/L PR Classification Guidelines:

This guide helps classify merged pull requests by effort and complexity rather than just line count. The goal is to assess the difficulty and scope of changes after they have been completed.

Small (S)

Characteristics:

  • Simple bug fixes, typos, or minor refactoring
  • Single-purpose changes affecting 1-2 files
  • Documentation updates
  • Configuration tweaks
  • Changes that require minimal context to review

Review Effort: Would have taken 5-10 minutes

Examples:

  • Fix typo in variable name
  • Update README with new instructions
  • Adjust configuration values
  • Simple one-line bug fixes
  • Import statement cleanup

Medium (M)

Characteristics:

  • Feature additions or enhancements
  • Refactoring that touches multiple files but maintains existing behavior
  • Breaking changes with backward compatibility
  • Changes requiring some domain knowledge to review

Review Effort: Would have taken 15-30 minutes

Examples:

  • Add new feature or component
  • Refactor common utility functions
  • Update dependencies with minor breaking changes
  • Add new component with tests
  • Performance optimizations
  • More complex bug fixes

Large (L)

Characteristics:

  • Major feature implementations
  • Breaking changes or API redesigns
  • Complex refactoring across multiple modules
  • New architectural patterns or significant design changes
  • Changes requiring deep context and multiple review rounds

Review Effort: Would have taken 45+ minutes

Examples:

  • Complete new feature with frontend/backend changes
  • Protocol upgrades or breaking changes
  • Major architectural refactoring
  • Framework or technology upgrades

Additional Factors to Consider

When deciding between sizes, also consider:

  • Test coverage impact: More comprehensive test changes lean toward larger classification
  • Risk level: Changes to critical systems bump up a size category
  • Team familiarity: Novel patterns or technologies increase complexity

Notes:

  • the assessment must be for the totality of the PR, that means comparing the base branch to the last commit of the PR
  • the assessment output must be exactly one of: S, M or L (single-line comment) in format of: SIZE={S/M/L}
  • do not include any additional text, only the size classification
  • your assessment comment must not include tips or additional sections
  • do NOT tag me or anyone else on your comment

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 31, 2025

Tip

For best results, initiate chat on the files or code changes.

SIZE=L


🧠 Learnings used
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:42.275Z
Learning: For PR #1884, after each commit review, I should provide a new comment with a PR size report in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding irrelevant files such as lock files (package-lock.json, cargo.lock, etc.).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:42.275Z
Learning: After each commit in PR #1884, I should provide a new comment with the PR size report in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`. The report should exclude irrelevant files such as lock files (e.g., package-lock.json, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:25:47.873Z
Learning: After each new commit review for rainlanguage/rain.orderbook repository, generate a PR size report in a separate comment with the format: "TOTAL=number ADDITIONS=number DELETIONS=number". This report should exclude irrelevant files such as lock files (e.g., package-lock.json, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:25:47.873Z
Learning: After each new commit review for rainlanguage/rain.orderbook repository, generate a PR size report in a separate comment with the exact format: "TOTAL=number\nADDITIONS=number\nDELETIONS=number". This report should exclude irrelevant files such as lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:14:22.646Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, I must consistently report the PR size after EVERY new commit in the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number" without any formatting blocks. The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock) and can be included either as part of the review or as a separate comment.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:14:22.646Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, I must consistently report the PR size after EVERY new commit in the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number" without any additional text or formatting blocks. The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock) and can be included either as part of the review or as a separate comment.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:46:08.530Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report should be the only content in the comment - no text before it, no text after it, no formatting blocks, just the raw report in the exact format: "TOTAL=number\nADDITIONS=number\nDELETIONS=number". The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1971
File: .github/workflows/vercel-docs-prod.yaml:32-34
Timestamp: 2025-07-11T12:30:09.245Z
Learning: findolor prefers not to pin Node versions explicitly in GitHub Actions workflows when using Nix with webapp-shell, considering the current setup sufficient for deterministic builds in the rainlanguage/rain.orderbook project.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1971
File: .github/workflows/vercel-docs-prod.yaml:10-14
Timestamp: 2025-07-11T12:29:49.284Z
Learning: In GitHub Actions workflows for the rainlanguage/rain.orderbook project, findolor is comfortable with job names that may seem misleading (like "Deploy-Docs-Preview" in a production workflow) when there's only one job in the workflow, as the context makes it clear enough.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2145
File: crates/common/src/raindex_client/local_db/query/create_tables/query.sql:71-72
Timestamp: 2025-10-06T11:44:07.888Z
Learning: The local DB feature in the rain.orderbook codebase is not live yet (as of PR #2145), so schema migrations for existing databases are not required when modifying table structures in `crates/common/src/raindex_client/local_db/query/create_tables/query.sql`.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:26:31.566Z
Learning: For PR #1884 and future PRs in rainlanguage/rain.orderbook repository, provide PR size reports in a separate comment with ONLY the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number", without any additional text or explanation. Reports should exclude irrelevant files such as lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2117
File: crates/js_api/src/gui/select_tokens.rs:421-424
Timestamp: 2025-09-02T08:04:34.729Z
Learning: User findolor in the rainlanguage/rain.orderbook codebase prefers not to change test code when tests are already passing, even if there appear to be type mismatches or potential issues. Working tests should be left alone unless there are actual errors.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1956
File: crates/common/src/fuzz/mod.rs:64-64
Timestamp: 2025-07-04T09:02:57.301Z
Learning: In rainlanguage/rain.orderbook, user findolor prefers to limit type consistency changes to only the parts directly related to the current work scope. For example, when updating chain_id fields from u64 to u32 in fuzz-related code, unrelated files like tauri-app wallet commands can remain as u64 if they serve different purposes and aren't part of the current changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants