Skip to content

Commit

Permalink
Merge pull request #3612 from mathesar-foundation/table_get
Browse files Browse the repository at this point in the history
Implement `tables.get` rpc endpoint
  • Loading branch information
mathemancer authored Jun 5, 2024
2 parents 63a82f0 + 97ae1a4 commit 9e23db0
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 1 deletion.
23 changes: 23 additions & 0 deletions db/sql/00_msar.sql
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,29 @@ SELECT EXISTS (SELECT 1 FROM pg_attribute WHERE attrelid=tab_id AND attname=col_
$$ LANGUAGE SQL RETURNS NULL ON NULL INPUT;


CREATE OR REPLACE FUNCTION msar.get_table(tab_id regclass) RETURNS jsonb AS $$/*
Given a table identifier, return a JSON object describing the table.
Each returned JSON object will have the form:
{
"oid": <int>,
"name": <str>,
"schema": <int>,
"description": <str>
}
Args:
tab_id: The OID or name of the table.
*/
SELECT jsonb_build_object(
'oid', oid,
'name', relname,
'schema', relnamespace,
'description', msar.obj_description(oid, 'pg_class')
) FROM pg_catalog.pg_class WHERE oid = tab_id;
$$ LANGUAGE SQL RETURNS NULL ON NULL INPUT;


CREATE OR REPLACE FUNCTION msar.get_table_info(sch_id regnamespace) RETURNS jsonb AS $$/*
Given a schema identifier, return an array of objects describing the tables of the schema.
Expand Down
22 changes: 22 additions & 0 deletions db/tables/operations/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,28 @@
MULTIPLE_RESULTS = 'multiple_results'


def get_table(table, conn):
"""
Return a dictionary describing a table of a schema.
The `table` can be given as either a "qualified name", or an OID.
The OID is the preferred identifier, since it's much more robust.
The returned dictionary is of the following form:
{
"oid": <int>,
"name": <str>,
"schema": <int>,
"description": <str>
}
Args:
table: The table for which we want table info.
"""
return exec_msar_func(conn, 'get_table', table).fetchone()[0]


def get_table_info(schema, conn):
"""
Return a list of dictionaries describing the tables of a schema.
Expand Down
1 change: 1 addition & 0 deletions docs/docs/api/rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ To use an RPC function:
options:
members:
- list_
- get_
- delete
- TableInfo

Expand Down
22 changes: 21 additions & 1 deletion mathesar/rpc/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from modernrpc.core import rpc_method, REQUEST_KEY
from modernrpc.auth.basic import http_basic_auth_login_required

from db.tables.operations.select import get_table_info
from db.tables.operations.select import get_table_info, get_table
from db.tables.operations.drop import drop_table_from_database
from mathesar.rpc.exceptions.handlers import handle_rpc_exceptions
from mathesar.rpc.utils import connect
Expand Down Expand Up @@ -47,6 +47,26 @@ def list_(*, schema_oid: int, database_id: int, **kwargs) -> list[TableInfo]:
]


@rpc_method(name="tables.get")
@http_basic_auth_login_required
@handle_rpc_exceptions
def get(*, table_oid: int, database_id: int, **kwargs) -> TableInfo:
"""
List information about a table for a schema.
Args:
table_oid: Identity of the table in the user's database.
database_id: The Django id of the database containing the table.
Returns:
Table details for a given table oid.
"""
user = kwargs.get(REQUEST_KEY).user
with connect(database_id, user) as conn:
raw_table_info = get_table(table_oid, conn)
return TableInfo(raw_table_info)


@rpc_method(name="tables.delete")
@http_basic_auth_login_required
@handle_rpc_exceptions
Expand Down
5 changes: 5 additions & 0 deletions mathesar/tests/rpc/test_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
"tables.list",
[user_is_authenticated]
),
(
tables.get,
"tables.get",
[user_is_authenticated]
),
(
tables.delete,
"tables.delete",
Expand Down
37 changes: 37 additions & 0 deletions mathesar/tests/rpc/test_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,43 @@ def mock_table_info(_schema_oid, conn):
assert actual_table_list == expect_table_list


def test_tables_get(rf, monkeypatch):
request = rf.post('/api/rpc/v0', data={})
request.user = User(username='alice', password='pass1234')
table_oid = 1964474
database_id = 11

@contextmanager
def mock_connect(_database_id, user):
if _database_id == database_id and user.username == 'alice':
try:
yield True
finally:
pass
else:
raise AssertionError('incorrect parameters passed')

def mock_table_get(_table_oid, conn):
if _table_oid != table_oid:
raise AssertionError('incorrect parameters passed')
return {
'oid': table_oid,
'name': 'Authors',
'schema': 2200,
'description': 'a description on the authors table.'
}
monkeypatch.setattr(tables, 'connect', mock_connect)
monkeypatch.setattr(tables, 'get_table', mock_table_get)
expect_table_list = {
'oid': table_oid,
'name': 'Authors',
'schema': 2200,
'description': 'a description on the authors table.'
}
actual_table_list = tables.get(table_oid=1964474, database_id=11, request=request)
assert actual_table_list == expect_table_list


def test_tables_delete(rf, monkeypatch):
request = rf.post('/api/rpc/v0', data={})
request.user = User(username='alice', password='pass1234')
Expand Down

0 comments on commit 9e23db0

Please sign in to comment.