bitbake: hashserv: Add database column query API

Adds an API to retrieve the columns that can be queried on from the
database backend. This prevents front end applications from needing to
hardcode the query columns

(Bitbake rev: abfce2b68bdab02ea2e9a63fbb3b9e270428a0a6)

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Joshua Watt 2023-11-03 08:26:34 -06:00 committed by Richard Purdie
parent 3a2c5a6fa2
commit c1574ae46f
6 changed files with 42 additions and 0 deletions

View File

@ -174,6 +174,10 @@ def main():
total_rows = sum(t["rows"] for t in usage.values())
print(f"Total rows: {total_rows}")
def handle_get_db_query_columns(args, client):
columns = client.get_db_query_columns()
print("\n".join(sorted(columns)))
parser = argparse.ArgumentParser(description='Hash Equivalence Client')
parser.add_argument('--address', default=DEFAULT_ADDRESS, help='Server address (default "%(default)s")')
parser.add_argument('--log', default='WARNING', help='Set logging level')
@ -239,6 +243,9 @@ def main():
db_usage_parser = subparsers.add_parser('get-db-usage', help="Database Usage")
db_usage_parser.set_defaults(func=handle_get_db_usage)
db_query_columns_parser = subparsers.add_parser('get-db-query-columns', help="Show columns that can be used in database queries")
db_query_columns_parser.set_defaults(func=handle_get_db_query_columns)
args = parser.parse_args()
logger = logging.getLogger('hashserv')

View File

@ -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):

View File

@ -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"])

View File

@ -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)

View File

@ -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)

View File

@ -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):