Skip to content

Commit

Permalink
Merge pull request #3653 from mathesar-foundation/columns_meta_rpc_patch
Browse files Browse the repository at this point in the history
Columns meta rpc patch
  • Loading branch information
Anish9901 authored Jul 3, 2024
2 parents 02c295a + 9f8115d commit 29172e0
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 3 deletions.
2 changes: 2 additions & 0 deletions docs/docs/api/rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ To use an RPC function:
options:
members:
- list_
- patch
- ColumnMetaData
- SettableColumnMetaData

## Responses

Expand Down
67 changes: 66 additions & 1 deletion mathesar/rpc/columns/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from modernrpc.auth.basic import http_basic_auth_login_required

from mathesar.rpc.exceptions.handlers import handle_rpc_exceptions
from mathesar.utils.columns import get_columns_meta_data
from mathesar.utils.columns import get_columns_meta_data, patch_columns_meta_data


class ColumnMetaData(TypedDict):
Expand Down Expand Up @@ -73,6 +73,42 @@ def from_model(cls, model):
)


class SettableColumnMetaData(TypedDict):
"""
Settable metadata fields for a column in a table.
Attributes:
attnum: The attnum of the column in the table.
bool_input: How the input for a boolean column should be shown.
bool_true: A string to display for `true` values.
bool_false: A string to display for `false` values.
num_min_frac_digits: Minimum digits shown after the decimal point.
num_max_frac_digits: Maximum digits shown after the decimal point.
num_show_as_perc: Whether to show a numeric value as a percentage.
mon_currency_symbol: The currency symbol shown for money value.
mon_currency_location: Where the currency symbol should be shown.
time_format: A string representing the format of time values.
date_format: A string representing the format of date values.
duration_min: The smallest unit for displaying durations.
duration_max: The largest unit for displaying durations.
duration_show_units: Whether to show the units for durations.
"""
attnum: int
bool_input: Optional[Literal["dropdown", "checkbox"]]
bool_true: Optional[str]
bool_false: Optional[str]
num_min_frac_digits: Optional[int]
num_max_frac_digits: Optional[int]
num_show_as_perc: Optional[bool]
mon_currency_symbol: Optional[str]
mon_currency_location: Optional[Literal["after-minus", "end-with-space"]]
time_format: Optional[str]
date_format: Optional[str]
duration_min: Optional[str]
duration_max: Optional[str]
duration_show_units: Optional[bool]


@rpc_method(name="columns.metadata.list")
@http_basic_auth_login_required
@handle_rpc_exceptions
Expand All @@ -91,3 +127,32 @@ def list_(*, table_oid: int, database_id: int, **kwargs) -> list[ColumnMetaData]
return [
ColumnMetaData.from_model(model) for model in columns_meta_data
]


@rpc_method(name="columns.metadata.patch")
@http_basic_auth_login_required
@handle_rpc_exceptions
def patch(
*,
column_meta_data_list: list[SettableColumnMetaData],
table_oid: int,
database_id: int,
**kwargs
) -> list[ColumnMetaData]:
"""
Alter metadata settings associated with columns of a table for a database.
Args:
column_meta_data_list: A list describing desired metadata alterations.
table_oid: Identity of the table whose metadata we'll modify.
database_id: The Django id of the database containing the table.
Returns:
List of altered metadata objects.
"""
columns_meta_data = patch_columns_meta_data(
column_meta_data_list, table_oid, database_id
)
return [
ColumnMetaData.from_model(model) for model in columns_meta_data
]
54 changes: 54 additions & 0 deletions mathesar/tests/rpc/columns/test_c_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,57 @@ def mock_get_columns_meta_data(_table_oid, _database_id):
]
actual_metadata_list = metadata.list_(table_oid=table_oid, database_id=database_id)
assert actual_metadata_list == expect_metadata_list


# TODO consider mocking out ColumnMetaData queryset for this test
def test_columns_meta_data_patch(monkeypatch):
database_id = 2
table_oid = 123456
expect_metadata_list = [
metadata.ColumnMetaData(
database_id=database_id, table_oid=table_oid, attnum=2,
bool_input="dropdown", bool_true="TRUE", bool_false="FALSE",
num_min_frac_digits=5, num_max_frac_digits=10, num_show_as_perc=False,
mon_currency_symbol="EUR", mon_currency_location="end-with-space",
time_format=None, date_format=None,
duration_min=None, duration_max=None, duration_show_units=True,
),
metadata.ColumnMetaData(
database_id=database_id, table_oid=table_oid, attnum=8,
bool_input="checkbox", bool_true="true", bool_false="false",
num_min_frac_digits=2, num_max_frac_digits=8, num_show_as_perc=True,
mon_currency_symbol="$", mon_currency_location="after-minus",
time_format=None, date_format=None,
duration_min=None, duration_max=None, duration_show_units=True,
),
]

def mock_patch_columns_meta_data(column_meta_data_list, _table_oid, _database_id):
server_model = Server(id=2, host='example.com', port=5432)
db_model = Database(id=_database_id, name='mymathesardb', server=server_model)
return [
ColumnMetaData(
database=db_model, table_oid=_table_oid, attnum=2,
bool_input="dropdown", bool_true="TRUE", bool_false="FALSE",
num_min_frac_digits=5, num_max_frac_digits=10, num_show_as_perc=False,
mon_currency_symbol="EUR", mon_currency_location="end-with-space",
time_format=None, date_format=None,
duration_min=None, duration_max=None, duration_show_units=True,
),
ColumnMetaData(
database=db_model, table_oid=_table_oid, attnum=8,
bool_input="checkbox", bool_true="true", bool_false="false",
num_min_frac_digits=2, num_max_frac_digits=8, num_show_as_perc=True,
mon_currency_symbol="$", mon_currency_location="after-minus",
time_format=None, date_format=None,
duration_min=None, duration_max=None, duration_show_units=True,
)
]

monkeypatch.setattr(metadata, "patch_columns_meta_data", mock_patch_columns_meta_data)
actual_metadata_list = metadata.patch(
column_meta_data_list=expect_metadata_list,
table_oid=table_oid,
database_id=database_id
)
assert actual_metadata_list == expect_metadata_list
5 changes: 5 additions & 0 deletions mathesar/tests/rpc/test_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
"columns.metadata.list",
[user_is_authenticated]
),
(
columns.metadata.patch,
"columns.metadata.patch",
[user_is_authenticated]
),
(
connections.add_from_known_connection,
"connections.add_from_known_connection",
Expand Down
19 changes: 17 additions & 2 deletions mathesar/utils/columns.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
from mathesar.models.base import ColumnMetaData
from mathesar.models.base import ColumnMetaData, Database


def get_columns_meta_data(table_oid, database_id):
return ColumnMetaData.filter(database__id=database_id, table_oid=table_oid)
return ColumnMetaData.objects.filter(
database__id=database_id, table_oid=table_oid
)


def patch_columns_meta_data(column_meta_data_list, table_oid, database_id):
db_model = Database.objects.get(id=database_id)
for meta_data_dict in column_meta_data_list:
# TODO decide if this is worth the trouble of doing in bulk.
ColumnMetaData.objects.update_or_create(
database=db_model,
table_oid=table_oid,
attnum=meta_data_dict["attnum"],
defaults=meta_data_dict
)
return get_columns_meta_data(table_oid, database_id)

0 comments on commit 29172e0

Please sign in to comment.