Skip to content

Commit 0c27a31

Browse files
authored
Fix formula migration data source filter compat on template import (baserow#4125)
* Fix formula migration data source filter compat * Remove formula error log to prevent noise
1 parent 44ca4f8 commit 0c27a31

File tree

4 files changed

+118
-25
lines changed

4 files changed

+118
-25
lines changed

backend/src/baserow/contrib/integrations/local_baserow/mixins.py

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -130,26 +130,32 @@ def deserialize_filters(self, value, id_mapping):
130130
:return: the deserialized version for the filter.
131131
"""
132132

133-
return [
134-
{
135-
**f,
136-
"field_id": (
137-
id_mapping["database_fields"][f["field_id"]]
138-
if "database_fields" in id_mapping
139-
else f["field_id"]
140-
),
141-
"value": (
142-
id_mapping["database_field_select_options"].get(
143-
int(f["value"]["formula"]), f["value"]["formula"]
133+
result = []
134+
135+
for f in value:
136+
formula = BaserowFormulaObject.to_formula(f["value"])
137+
field_id = id_mapping.get("database_fields", {}).get(
138+
f["field_id"], f["field_id"]
139+
)
140+
141+
if (
142+
f["value_is_formula"]
143+
or not formula["formula"].isdigit()
144+
or "database_field_select_options" not in id_mapping
145+
):
146+
val = formula
147+
else:
148+
val = BaserowFormulaObject.create(
149+
formula=str(
150+
id_mapping["database_field_select_options"].get(
151+
int(formula["formula"]), formula["formula"]
152+
)
144153
)
145-
if "database_field_select_options" in id_mapping
146-
and f["value"]["formula"].isdigit()
147-
and not f["value_is_formula"]
148-
else f["value"]["formula"]
149-
),
150-
}
151-
for f in value
152-
]
154+
)
155+
156+
result.append({**f, "field_id": field_id, "value": val})
157+
158+
return result
153159

154160
def create_instance_from_serialized(
155161
self,

backend/src/baserow/core/formula/types.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,29 @@ def execute(self, context: FormulaContext, args: FormulaArgs) -> Any:
7878

7979

8080
class BaserowFormulaObject(TypedDict):
81-
version: str
82-
mode: BaserowFormulaMode
8381
formula: BaserowFormula
82+
mode: BaserowFormulaMode
83+
version: str
84+
85+
@classmethod
86+
def create(
87+
cls,
88+
formula: str = "",
89+
mode: BaserowFormulaMode = BASEROW_FORMULA_MODE_SIMPLE,
90+
version: str = "0.1",
91+
) -> "BaserowFormulaObject":
92+
return BaserowFormulaObject(formula=formula, mode=mode, version=version)
93+
94+
@classmethod
95+
def to_formula(cls, value) -> "BaserowFormulaObject":
96+
"""
97+
Return a formula object even if it was a string.
98+
"""
99+
100+
if isinstance(value, dict):
101+
return value
102+
else:
103+
return cls.create(formula=value)
84104

85105

86106
class BaserowFormulaMinified(TypedDict):

backend/tests/baserow/contrib/integrations/local_baserow/test_mixins.py

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,23 @@ def test_local_baserow_table_service_filterable_mixin_import_export(data_fixture
132132
page=page, table=table, integration=integration
133133
)
134134
data_fixture.create_local_baserow_table_service_filter(
135-
service=data_source.service, field=text_field, value="'foobar'", order=0
135+
service=data_source.service,
136+
field=text_field,
137+
value="'foobar'",
138+
order=0,
139+
value_is_formula=True,
136140
)
137141
data_fixture.create_local_baserow_table_service_filter(
138-
service=data_source.service, field=text_field, value="123", order=1
142+
service=data_source.service,
143+
field=text_field,
144+
value="123",
145+
order=1,
146+
value_is_formula=True,
139147
)
140148
data_fixture.create_local_baserow_table_service_filter(
141149
service=data_source.service,
142150
field=single_select_field,
151+
value_is_formula=False,
143152
value=str(single_option.id),
144153
order=2,
145154
)
@@ -181,18 +190,24 @@ def test_local_baserow_table_service_filterable_mixin_import_export(data_fixture
181190
imported_page = imported_builder.visible_pages.get()
182191
imported_datasource = imported_page.datasource_set.get()
183192
imported_filters = [
184-
{"field_id": sf.field_id, "value": sf.value}
193+
{
194+
"field_id": sf.field_id,
195+
"value": sf.value,
196+
"value_is_formula": sf.value_is_formula,
197+
}
185198
for sf in imported_datasource.service.service_filters.all()
186199
]
187200

188201
assert imported_filters == [
189202
{
190203
"field_id": imported_text_field.id,
191204
"value": {"mode": "simple", "version": "0.1", "formula": "'foobar'"},
205+
"value_is_formula": True,
192206
},
193207
{
194208
"field_id": imported_text_field.id,
195209
"value": {"mode": "simple", "version": "0.1", "formula": "123"},
210+
"value_is_formula": True,
196211
},
197212
{
198213
"field_id": imported_single_select_field.id,
@@ -201,6 +216,59 @@ def test_local_baserow_table_service_filterable_mixin_import_export(data_fixture
201216
"version": "0.1",
202217
"formula": str(imported_select_option.id),
203218
},
219+
"value_is_formula": False,
220+
},
221+
]
222+
223+
224+
@pytest.mark.django_db()
225+
def test_local_baserow_table_service_filterable_mixin_compat():
226+
mixin = LocalBaserowTableServiceFilterableMixin()
227+
228+
id_mapping = {
229+
"database_field_select_options": {1: 42},
230+
"database_fields": {1: 41, 2: 42, 3: 43, 4: 44},
231+
}
232+
233+
value_to_test = [
234+
{"field_id": 1, "value": "'Formula as string'", "value_is_formula": True},
235+
{"field_id": 2, "value": "1", "value_is_formula": False},
236+
{"field_id": 3, "value": "", "value_is_formula": True},
237+
{
238+
"field_id": 4,
239+
"value": {"mode": "simple", "version": "0.1", "formula": "'foobar'"},
240+
"value_is_formula": True,
241+
},
242+
]
243+
244+
result = json.loads(
245+
json.dumps(mixin.deserialize_filters(value_to_test, id_mapping))
246+
)
247+
248+
assert result == [
249+
{
250+
"field_id": 41,
251+
"value": {
252+
"formula": "'Formula as string'",
253+
"mode": "simple",
254+
"version": "0.1",
255+
},
256+
"value_is_formula": True,
257+
},
258+
{
259+
"field_id": 42,
260+
"value": {"formula": "42", "mode": "simple", "version": "0.1"},
261+
"value_is_formula": False,
262+
},
263+
{
264+
"field_id": 43,
265+
"value": {"formula": "", "mode": "simple", "version": "0.1"},
266+
"value_is_formula": True,
267+
},
268+
{
269+
"field_id": 44,
270+
"value": {"mode": "simple", "version": "0.1", "formula": "'foobar'"},
271+
"value_is_formula": True,
204272
},
205273
]
206274

web-frontend/modules/core/formula/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export const resolveFormula = (
2323
const tree = parseBaserowFormula(formulaCtx.formula)
2424
return new JavascriptExecutor(functions, RuntimeFormulaContext).visit(tree)
2525
} catch (err) {
26-
console.log('Error while parsing or executing formula:', err)
2726
return ''
2827
}
2928
}

0 commit comments

Comments
 (0)