Skip to content

Commit

Permalink
feat(queries,cli): print iroha json query results row-wise
Browse files Browse the repository at this point in the history
This is more natural for humans than the columnar format iroha uses in transit

Signed-off-by: ⭐️NINIKA⭐️ <[email protected]>
  • Loading branch information
DCNick3 committed Nov 21, 2024
1 parent d9a19db commit 8411d38
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
28 changes: 25 additions & 3 deletions crates/iroha_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1149,18 +1149,40 @@ mod json {
// we can't really do type-erased iterable queries in a nice way right now...
use iroha::data_model::query::builder::QueryExecutor;

let (mut first_batch, _remaining_items, mut continue_cursor) =
let (mut accumulated_batch, _remaining_items, mut continue_cursor) =
client.start_query(query)?;

while let Some(cursor) = continue_cursor {
let (next_batch, _remaining_items, next_continue_cursor) =
<Client as QueryExecutor>::continue_query(cursor)?;

first_batch.extend(next_batch);
accumulated_batch.extend(next_batch);
continue_cursor = next_continue_cursor;
}

context.print_data(&first_batch)?;
// for efficiency reasons iroha encodes query results in a columnar format,
// so we need to transpose the batch to get the format that is more natural for humans
let mut batches = vec![Vec::new(); accumulated_batch.len()];
for batch in accumulated_batch.into_iter() {
// downcast to json and extract the actual array
// dynamic typing is just easier to use here than introducing a bunch of new types only for iroha_cli
let batch = serde_json::to_value(batch)?;
let serde_json::Value::Object(batch) = batch else {
panic!("Expected the batch serialization to be a JSON object");
};
let (_ty, batch) = batch
.into_iter()
.next()
.expect("Expected the batch to have exactly one key");
let serde_json::Value::Array(batch_vec) = batch else {
panic!("Expected the batch payload to be a JSON array");
};
for (target, value) in batches.iter_mut().zip(batch_vec) {
target.push(value);
}
}

context.print_data(&batches)?;
}
}

Expand Down
12 changes: 11 additions & 1 deletion crates/iroha_data_model/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,17 @@ impl QueryOutputBatchBoxTuple {
/// Returns length of this batch tuple
// This works under assumption that all batches in the tuples have the same length, which should be true for iroha
pub fn len(&self) -> usize {
self.tuple.iter().map(QueryOutputBatchBox::len).sum()
self.tuple[0].len()
}

/// Returns an iterator over the batches in this tuple
pub fn iter(&self) -> impl Iterator<Item = &QueryOutputBatchBox> {
self.tuple.iter()
}

/// Consumes this batch tuple and returns an iterator over the batches
pub fn into_iter(self) -> impl Iterator<Item = QueryOutputBatchBox> {
self.tuple.into_iter()
}
}

Expand Down

0 comments on commit 8411d38

Please sign in to comment.