Repository: mathesar-foundation/mathesar

Issue:
Implement `tables.get` RPC method



Discussion:

Resolving patch:
diff --git a/db/tables/operations/select.py b/db/tables/operations/select.py
--- a/db/tables/operations/select.py
+++ b/db/tables/operations/select.py
@@ -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.
diff --git a/mathesar/rpc/tables.py b/mathesar/rpc/tables.py
--- a/mathesar/rpc/tables.py
+++ b/mathesar/rpc/tables.py
@@ -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
@@ -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


Test patch:
diff --git a/mathesar/tests/rpc/test_endpoints.py b/mathesar/tests/rpc/test_endpoints.py
--- a/mathesar/tests/rpc/test_endpoints.py
+++ b/mathesar/tests/rpc/test_endpoints.py
@@ -49,6 +49,11 @@
         "tables.list",
         [user_is_authenticated]
     ),
+    (
+        tables.get,
+        "tables.get",
+        [user_is_authenticated]
+    ),
     (
         tables.delete,
         "tables.delete",
diff --git a/mathesar/tests/rpc/test_tables.py b/mathesar/tests/rpc/test_tables.py
--- a/mathesar/tests/rpc/test_tables.py
+++ b/mathesar/tests/rpc/test_tables.py
@@ -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')