aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hashserv
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hashserv')
-rw-r--r--lib/hashserv/client.py5
-rw-r--r--lib/hashserv/server.py5
-rw-r--r--lib/hashserv/sqlalchemy.py10
-rw-r--r--lib/hashserv/sqlite.py7
-rw-r--r--lib/hashserv/tests.py8
5 files changed, 35 insertions, 0 deletions
diff --git a/lib/hashserv/client.py b/lib/hashserv/client.py
index 5e0a462b1..35a97687f 100644
--- a/lib/hashserv/client.py
+++ b/lib/hashserv/client.py
@@ -190,6 +190,10 @@ class AsyncClient(bb.asyncrpc.AsyncClient):
await self._set_mode(self.MODE_NORMAL)
return (await self.invoke({"get-db-usage": {}}))["usage"]
+ async def get_db_query_columns(self):
+ await self._set_mode(self.MODE_NORMAL)
+ return (await self.invoke({"get-db-query-columns": {}}))["columns"]
+
class Client(bb.asyncrpc.Client):
def __init__(self, username=None, password=None):
@@ -219,6 +223,7 @@ class Client(bb.asyncrpc.Client):
"delete_user",
"become_user",
"get_db_usage",
+ "get_db_query_columns",
)
def _get_async_client(self):
diff --git a/lib/hashserv/server.py b/lib/hashserv/server.py
index c5b9797e4..8c3d20b65 100644
--- a/lib/hashserv/server.py
+++ b/lib/hashserv/server.py
@@ -250,6 +250,7 @@ class ServerClient(bb.asyncrpc.AsyncServerConnection):
"get-stream": self.handle_get_stream,
"get-stats": self.handle_get_stats,
"get-db-usage": self.handle_get_db_usage,
+ "get-db-query-columns": self.handle_get_db_query_columns,
# Not always read-only, but internally checks if the server is
# read-only
"report": self.handle_report,
@@ -572,6 +573,10 @@ class ServerClient(bb.asyncrpc.AsyncServerConnection):
async def handle_get_db_usage(self, request):
return {"usage": await self.db.get_usage()}
+ @permissions(DB_ADMIN_PERM)
+ async def handle_get_db_query_columns(self, request):
+ return {"columns": await self.db.get_query_columns()}
+
# The authentication API is always allowed
async def handle_auth(self, request):
username = str(request["username"])
diff --git a/lib/hashserv/sqlalchemy.py b/lib/hashserv/sqlalchemy.py
index 818b51951..cee04bffb 100644
--- a/lib/hashserv/sqlalchemy.py
+++ b/lib/hashserv/sqlalchemy.py
@@ -415,3 +415,13 @@ class Database(object):
}
return usage
+
+ async def get_query_columns(self):
+ columns = set()
+ for table in (UnihashesV2, OuthashesV2):
+ for c in table.__table__.columns:
+ if not isinstance(c.type, Text):
+ continue
+ columns.add(c.key)
+
+ return list(columns)
diff --git a/lib/hashserv/sqlite.py b/lib/hashserv/sqlite.py
index dfdccbbaa..f65036be9 100644
--- a/lib/hashserv/sqlite.py
+++ b/lib/hashserv/sqlite.py
@@ -399,3 +399,10 @@ class Database(object):
"rows": cursor.fetchone()[0],
}
return usage
+
+ async def get_query_columns(self):
+ columns = set()
+ for name, typ, _ in UNIHASH_TABLE_DEFINITION + OUTHASH_TABLE_DEFINITION:
+ if typ.startswith("TEXT"):
+ columns.add(name)
+ return list(columns)
diff --git a/lib/hashserv/tests.py b/lib/hashserv/tests.py
index 9d5bec245..fc69acaf7 100644
--- a/lib/hashserv/tests.py
+++ b/lib/hashserv/tests.py
@@ -776,6 +776,14 @@ class HashEquivalenceCommonTests(object):
self.assertIn("rows", usage[name])
self.assertTrue(isinstance(usage[name]["rows"], int))
+ def test_get_db_query_columns(self):
+ columns = self.client.get_db_query_columns()
+
+ self.assertTrue(isinstance(columns, list))
+ self.assertTrue(len(columns) > 0)
+
+ for col in columns:
+ self.client.remove({col: ""})
class TestHashEquivalenceUnixServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase):
def get_server_addr(self, server_idx):