Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions crates/controller/src/api/worksheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ impl<'a> Worksheet<'a> {
let (keys, fields, random_entries) = match s {
Schema::RowSchema(schema) => {
let keys = schema
.get_all_key_cell_ids(id)
.get_all_key_cell_ids(id, &block_place)
.into_iter()
.map(|cell_id| {
let idx = block_place
Expand Down Expand Up @@ -1015,7 +1015,7 @@ impl<'a> Worksheet<'a> {
}
Schema::ColSchema(schema) => {
let keys = schema
.get_all_key_cell_ids(id)
.get_all_key_cell_ids(id, &block_place)
.into_iter()
.map(|cell_id| {
let idx = block_place
Expand Down Expand Up @@ -1416,6 +1416,7 @@ impl<'a> Worksheet<'a> {
let block_place = self.get_block_place(block_id)?;
let (row_cnt, col_cnt) = block_place.get_block_size();
let (row_start, col_start) = self.get_block_master_cell(block_id)?;
let bp = self.controller.status.navigator.get_block_place(&self.sheet_id, &block_id)?;
let schema = self
.controller
.status
Expand Down Expand Up @@ -1443,7 +1444,7 @@ impl<'a> Worksheet<'a> {
let (keys, fields, random_entries) = match s {
Schema::RowSchema(schema) => {
let keys = schema
.get_all_key_cell_ids(block_id)
.get_all_key_cell_ids(block_id, bp)
.into_iter()
.map(|cell_id| {
let idx = block_place
Expand Down Expand Up @@ -1474,7 +1475,7 @@ impl<'a> Worksheet<'a> {
}
Schema::ColSchema(schema) => {
let keys = schema
.get_all_key_cell_ids(block_id)
.get_all_key_cell_ids(block_id, bp)
.into_iter()
.map(|cell_id| {
let idx = block_place
Expand Down
14 changes: 12 additions & 2 deletions crates/controller/src/block_manager/schema_manager/manager.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use imbl::HashMap;
use logisheets_base::{BlockCellId, BlockId, SheetId};

use crate::navigator::BlockPlace;

use super::schema::{Field, RenderId, Schema, SchemaTrait};

#[derive(Debug, Clone, Default)]
Expand Down Expand Up @@ -30,10 +32,18 @@ impl SchemaManager {
schema.partially_resolve(key, field)
}

pub fn get_all_key_cell_ids(&self, ref_name: &str) -> Option<(SheetId, Vec<BlockCellId>)> {
pub fn get_all_key_cell_ids<'a, F>(
&'a self,
ref_name: &str,
f: &'a F,
) -> Option<(SheetId, Vec<BlockCellId>)>
where
F: Fn(&'a SheetId, &'a BlockId) -> Option<&'a BlockPlace>,
{
let (sheet_id, block_id) = self.refs.get(ref_name)?;
let schema = self.schemas.get(&(*sheet_id, *block_id))?;
Some((*sheet_id, schema.get_all_key_cell_ids(*block_id)))
let bp = f(sheet_id, block_id)?;
Some((*sheet_id, schema.get_all_key_cell_ids(*block_id, bp)))
}

#[inline]
Expand Down
34 changes: 18 additions & 16 deletions crates/controller/src/block_manager/schema_manager/schema.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use logisheets_base::{BlockCellId, BlockId, ColId, RowId};

use crate::navigator::BlockPlace;

pub type RowSchema = FormSchema<ColId, RowId, true>;
pub type ColSchema = FormSchema<RowId, ColId, false>;
pub type RenderId = String;
Expand Down Expand Up @@ -52,11 +54,11 @@ impl SchemaTrait for Schema {
}
}

fn get_all_key_cell_ids(&self, block_id: BlockId) -> Vec<BlockCellId> {
fn get_all_key_cell_ids(&self, block_id: BlockId, bp: &BlockPlace) -> Vec<BlockCellId> {
match self {
Schema::RowSchema(form_schema) => form_schema.get_all_key_cell_ids(block_id),
Schema::ColSchema(form_schema) => form_schema.get_all_key_cell_ids(block_id),
Schema::RandomSchema(random_schema) => random_schema.get_all_key_cell_ids(block_id),
Schema::RowSchema(form_schema) => form_schema.get_all_key_cell_ids(block_id, bp),
Schema::ColSchema(form_schema) => form_schema.get_all_key_cell_ids(block_id, bp),
Schema::RandomSchema(random_schema) => random_schema.get_all_key_cell_ids(block_id, bp),
}
}

Expand All @@ -73,7 +75,7 @@ pub trait SchemaTrait {
fn get_render_id(&self, row: RowId, col: ColId) -> Option<RenderId>;
fn get_ref_name(&self) -> String;
fn get_all_fields(&self) -> Vec<Field>;
fn get_all_key_cell_ids(&self, block_id: BlockId) -> Vec<BlockCellId>;
fn get_all_key_cell_ids(&self, block_id: BlockId, bp: &BlockPlace) -> Vec<BlockCellId>;
fn partially_resolve(&self, key: BlockCellId, field: &String) -> Option<BlockCellId>;
}

Expand All @@ -93,14 +95,14 @@ impl SchemaTrait for RowSchema {
self.fields.iter().map(|(f, _)| f.clone()).collect()
}

fn get_all_key_cell_ids(&self, block_id: BlockId) -> Vec<BlockCellId> {
fn get_all_key_cell_ids(&self, block_id: BlockId, bp: &BlockPlace) -> Vec<BlockCellId> {
let key = self.key;
self.fields
bp.rows
.iter()
.map(|(_, (f, _))| BlockCellId {
.map(|r| BlockCellId {
block_id,
row: key,
col: *f,
row: *r,
col: key,
})
.collect()
}
Expand Down Expand Up @@ -136,14 +138,14 @@ impl SchemaTrait for ColSchema {
self.fields.iter().map(|(f, _)| f.clone()).collect()
}

fn get_all_key_cell_ids(&self, block_id: BlockId) -> Vec<BlockCellId> {
fn get_all_key_cell_ids(&self, block_id: BlockId, bp: &BlockPlace) -> Vec<BlockCellId> {
let key = self.key;
self.fields
bp.cols
.iter()
.map(|(_, (f, _))| BlockCellId {
.map(|c| BlockCellId {
block_id,
row: *f,
col: key,
row: key,
col: *c,
})
.collect()
}
Expand Down Expand Up @@ -179,7 +181,7 @@ impl SchemaTrait for RandomSchema {
.collect()
}

fn get_all_key_cell_ids(&self, block_id: BlockId) -> Vec<BlockCellId> {
fn get_all_key_cell_ids(&self, block_id: BlockId, _bp: &BlockPlace) -> Vec<BlockCellId> {
self.key_field
.iter()
.map(|(_, r, c, _)| BlockCellId {
Expand Down
8 changes: 6 additions & 2 deletions crates/controller/src/connectors/calc_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ use logisheets_base::{
matrix_value::{cross_product_usize, MatrixValue},
Addr, CellId, CellValue, Error, FuncId, NameId, SheetId, TextId,
};
use logisheets_base::{BlockCellId, BlockRange, CubeCross, NormalRange, Range};
use logisheets_base::{BlockCellId, BlockId, BlockRange, CubeCross, NormalRange, Range};
use logisheets_parser::ast;

use crate::block_manager::schema_manager::SchemaManager;
use crate::cube_manager::CubeManager;
use crate::id_manager::SheetIdManager;
use crate::navigator::BlockPlace;
use crate::range_manager::RangeManager;
use crate::{
async_func_manager::AsyncFuncManager,
Expand Down Expand Up @@ -549,9 +550,12 @@ where

impl<'a> BlockRefTrait for CalcConnector<'a> {
fn get_all_keys(&self, ref_name: &str) -> Vec<(String, SheetId, BlockCellId)> {
let f = |sheet_id: &SheetId, block_id: &BlockId| -> Option<&BlockPlace> {
self.navigator.get_block_place(sheet_id, block_id).ok()
};
let (sheet_id, block_ids) = self
.block_schema_manager
.get_all_key_cell_ids(ref_name)
.get_all_key_cell_ids(ref_name, &f)
.unwrap_or_default();
let text_fetcher = |id: TextId| self.text_id_manager.get_string(&id).unwrap().clone();
block_ids
Expand Down
2 changes: 0 additions & 2 deletions crates/controller/src/connectors/range_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use logisheets_base::{

use crate::{
ext_book_manager::ExtBooksManager,
formula_manager::FormulaManager,
id_manager::{FuncIdManager, NameIdManager, SheetIdManager, TextIdManager},
navigator::Navigator,
range_manager::ctx::RangeExecCtx,
Expand All @@ -24,7 +23,6 @@ pub struct RangeConnector<'a> {
pub external_links_manager: &'a mut ExtBooksManager,
pub navigator: &'a Navigator,
pub sheet_pos_manager: &'a SheetInfoManager,
pub formula_manager: &'a FormulaManager,
}

impl<'a> IdFetcherTrait for RangeConnector<'a> {
Expand Down
1 change: 0 additions & 1 deletion crates/controller/src/controller/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,6 @@ impl<'a> Executor<'a> {
external_links_manager: &mut self.status.external_links_manager,
navigator: &self.status.navigator,
sheet_pos_manager: &self.status.sheet_info_manager,
formula_manager: &self.status.formula_manager,
};
let executor = RangeExecutor::new(self.status.range_manager.clone());
executor.execute(&ctx, payload)
Expand Down
14 changes: 14 additions & 0 deletions crates/controller/src/edit_action/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,12 @@ pub struct BindFormSchema {
pub row: bool,
}

impl From<BindFormSchema> for EditPayload {
fn from(value: BindFormSchema) -> Self {
EditPayload::BindFormSchema(value)
}
}

#[derive(Debug, Clone, TS)]
#[ts(file_name = "bind_random_schema.ts", builder, rename_all = "camelCase")]
pub struct BindRandomSchema {
Expand All @@ -467,6 +473,12 @@ pub struct BindRandomSchema {
pub units: Vec<RandomSchemaUnit>,
}

impl From<BindRandomSchema> for EditPayload {
fn from(value: BindRandomSchema) -> Self {
EditPayload::BindRandomSchema(value)
}
}

#[derive(Debug, Clone, TS)]
#[ts(file_name = "random_schema_unit.ts", builder, rename_all = "camelCase")]
pub struct RandomSchemaUnit {
Expand Down Expand Up @@ -989,6 +1001,8 @@ impl Payload for LineFormatBrush {}
impl Payload for EphemeralCellInput {}
impl Payload for ConvertBlock {}
impl Payload for UpsertFieldRenderInfo {}
impl Payload for BindFormSchema{}
impl Payload for BindRandomSchema{}

#[cfg(test)]
mod tests {
Expand Down
4 changes: 2 additions & 2 deletions crates/wasms/server/src/controller.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use logisheets_rs::{
lex_and_fmt, lex_success, AppData, AsyncCalcResult, AsyncErr, AsyncFuncResult, BasicError,
BlockId, ColId, EditAction, EditPayload, Error, PayloadsAction, RowId, RowInfo, SaveFileResult,
SheetCellId, SheetId, Workbook,
BlockId, ColId, EditAction, Error, PayloadsAction, RowId, RowInfo, SaveFileResult, SheetCellId,
SheetId, Workbook,
};
use singlyton::{Singleton, SingletonUninit};
use wasm_bindgen::prelude::*;
Expand Down
10 changes: 10 additions & 0 deletions resources/funcs/blockref.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "BLOCKREF",
"description": "functions.blockref.description",
"argCount": {"eq": 3},
"args": [
{"argName": "ref"},
{"argName": "key"},
{"argName": "field"}
]
}
10 changes: 10 additions & 0 deletions resources/funcs/blockrefs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "BLOCKREFS",
"description": "functions.blockrefs.description",
"argCount": {"eq": 3},
"args": [
{"argName": "ref"},
{"argName": "keyFilter"},
{"argName": "fieldFilter"}
]
}
6 changes: 6 additions & 0 deletions resources/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@
"bitrshift": {
"description": "Shifts bits of a number to the right by a specified number of positions."
},
"blockref": {
"description": "Fetches a block cell value through its key and field"
},
"blockrefs": {
"description": "Fetches block cell values whose key and field matches conditions"
},
"rand": {
"description": "Returns an evenly distributed random real number greater than or equal to 0 and less than 1."
},
Expand Down
20 changes: 20 additions & 0 deletions tests/funcs/block_ref_data.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
BLOCKCREATE 1 A1:C4

# A B(field1) C(field2)
# 1 key1 4 7
# 2 key2 5 8
# 3 key3 6 9
# 4 kye4 10 11

INPUT A1 key1
INPUT A2 key2
INPUT A3 key3
INPUT A4 kye4
INPUT B1 4
INPUT B2 5
INPUT B3 6
INPUT B4 10
INPUT C1 7
INPUT C2 8
INPUT C3 9
INPUT C4 11
45 changes: 44 additions & 1 deletion tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ mod common;

#[cfg(test)]
mod funcs {

use glob::glob;
use logisheets::EditAction;

use crate::test_script;
use crate::{load_script, test_script};
use logisheets_controller::edit_action::{BindFormSchema, CellInput, PayloadsAction};

#[test]
fn test_funcs() {
Expand All @@ -38,6 +41,46 @@ mod funcs {
test_script(path)
});
}

#[test]
fn test_block_ref() {
let mut wb = load_script("tests/funcs/block_ref_data.script");
wb.handle_action(EditAction::Payloads(
PayloadsAction::new()
.add_payload(BindFormSchema {
ref_name: "test_ref".to_string(),
sheet_idx: 0,
block_id: 1, // check it in the script
field_from: 1,
key_idx: 0,
fields: vec![String::from("field1"), String::from("field2")],
render_ids: vec![String::from("render1"), String::from("render2")],
row: true,
})
.add_payload(CellInput {
sheet_idx: 0,
row: 10,
col: 10,
content: String::from(r#"=BLOCKREF("test_ref", "key2", "field2")"#),
})
.add_payload(CellInput {
sheet_idx: 0,
row: 11,
col: 11,
content: String::from(r#"=SUM(BLOCKREFS("test_ref", "key*", "field2"))"#),
}),
));
let v = wb.get_sheet_by_idx(0).unwrap().get_value(10, 10).unwrap();
match v {
logisheets::Value::Number(v) => assert_eq!(v, 8.0),
_ => panic!("wrong result in blockref"),
}
let v = wb.get_sheet_by_idx(0).unwrap().get_value(11, 11).unwrap();
match v {
logisheets::Value::Number(v) => assert_eq!(v, 24.0),
_ => panic!("wrong result in blockrefs"),
}
}
}
#[cfg(test)]
mod shift;
Expand Down
Loading