diff options
| -rwxr-xr-x | bitbake/bin/bitbake-hashclient | 7 | ||||
| -rw-r--r-- | bitbake/lib/hashserv/client.py | 5 | ||||
| -rw-r--r-- | bitbake/lib/hashserv/server.py | 5 | ||||
| -rw-r--r-- | bitbake/lib/hashserv/sqlalchemy.py | 10 | ||||
| -rw-r--r-- | bitbake/lib/hashserv/sqlite.py | 7 | ||||
| -rw-r--r-- | bitbake/lib/hashserv/tests.py | 8 |
6 files changed, 42 insertions, 0 deletions
diff --git a/bitbake/bin/bitbake-hashclient b/bitbake/bin/bitbake-hashclient index 5d65c7bc56..58aa02ee55 100755 --- a/bitbake/bin/bitbake-hashclient +++ b/bitbake/bin/bitbake-hashclient | |||
| @@ -174,6 +174,10 @@ def main(): | |||
| 174 | total_rows = sum(t["rows"] for t in usage.values()) | 174 | total_rows = sum(t["rows"] for t in usage.values()) |
| 175 | print(f"Total rows: {total_rows}") | 175 | print(f"Total rows: {total_rows}") |
| 176 | 176 | ||
| 177 | def handle_get_db_query_columns(args, client): | ||
| 178 | columns = client.get_db_query_columns() | ||
| 179 | print("\n".join(sorted(columns))) | ||
| 180 | |||
| 177 | parser = argparse.ArgumentParser(description='Hash Equivalence Client') | 181 | parser = argparse.ArgumentParser(description='Hash Equivalence Client') |
| 178 | parser.add_argument('--address', default=DEFAULT_ADDRESS, help='Server address (default "%(default)s")') | 182 | parser.add_argument('--address', default=DEFAULT_ADDRESS, help='Server address (default "%(default)s")') |
| 179 | parser.add_argument('--log', default='WARNING', help='Set logging level') | 183 | parser.add_argument('--log', default='WARNING', help='Set logging level') |
| @@ -239,6 +243,9 @@ def main(): | |||
| 239 | db_usage_parser = subparsers.add_parser('get-db-usage', help="Database Usage") | 243 | db_usage_parser = subparsers.add_parser('get-db-usage', help="Database Usage") |
| 240 | db_usage_parser.set_defaults(func=handle_get_db_usage) | 244 | db_usage_parser.set_defaults(func=handle_get_db_usage) |
| 241 | 245 | ||
| 246 | db_query_columns_parser = subparsers.add_parser('get-db-query-columns', help="Show columns that can be used in database queries") | ||
| 247 | db_query_columns_parser.set_defaults(func=handle_get_db_query_columns) | ||
| 248 | |||
| 242 | args = parser.parse_args() | 249 | args = parser.parse_args() |
| 243 | 250 | ||
| 244 | logger = logging.getLogger('hashserv') | 251 | logger = logging.getLogger('hashserv') |
diff --git a/bitbake/lib/hashserv/client.py b/bitbake/lib/hashserv/client.py index 5e0a462b1c..35a97687fb 100644 --- a/bitbake/lib/hashserv/client.py +++ b/bitbake/lib/hashserv/client.py | |||
| @@ -190,6 +190,10 @@ class AsyncClient(bb.asyncrpc.AsyncClient): | |||
| 190 | await self._set_mode(self.MODE_NORMAL) | 190 | await self._set_mode(self.MODE_NORMAL) |
| 191 | return (await self.invoke({"get-db-usage": {}}))["usage"] | 191 | return (await self.invoke({"get-db-usage": {}}))["usage"] |
| 192 | 192 | ||
| 193 | async def get_db_query_columns(self): | ||
| 194 | await self._set_mode(self.MODE_NORMAL) | ||
| 195 | return (await self.invoke({"get-db-query-columns": {}}))["columns"] | ||
| 196 | |||
| 193 | 197 | ||
| 194 | class Client(bb.asyncrpc.Client): | 198 | class Client(bb.asyncrpc.Client): |
| 195 | def __init__(self, username=None, password=None): | 199 | def __init__(self, username=None, password=None): |
| @@ -219,6 +223,7 @@ class Client(bb.asyncrpc.Client): | |||
| 219 | "delete_user", | 223 | "delete_user", |
| 220 | "become_user", | 224 | "become_user", |
| 221 | "get_db_usage", | 225 | "get_db_usage", |
| 226 | "get_db_query_columns", | ||
| 222 | ) | 227 | ) |
| 223 | 228 | ||
| 224 | def _get_async_client(self): | 229 | def _get_async_client(self): |
diff --git a/bitbake/lib/hashserv/server.py b/bitbake/lib/hashserv/server.py index c5b9797e4e..8c3d20b651 100644 --- a/bitbake/lib/hashserv/server.py +++ b/bitbake/lib/hashserv/server.py | |||
| @@ -250,6 +250,7 @@ class ServerClient(bb.asyncrpc.AsyncServerConnection): | |||
| 250 | "get-stream": self.handle_get_stream, | 250 | "get-stream": self.handle_get_stream, |
| 251 | "get-stats": self.handle_get_stats, | 251 | "get-stats": self.handle_get_stats, |
| 252 | "get-db-usage": self.handle_get_db_usage, | 252 | "get-db-usage": self.handle_get_db_usage, |
| 253 | "get-db-query-columns": self.handle_get_db_query_columns, | ||
| 253 | # Not always read-only, but internally checks if the server is | 254 | # Not always read-only, but internally checks if the server is |
| 254 | # read-only | 255 | # read-only |
| 255 | "report": self.handle_report, | 256 | "report": self.handle_report, |
| @@ -572,6 +573,10 @@ class ServerClient(bb.asyncrpc.AsyncServerConnection): | |||
| 572 | async def handle_get_db_usage(self, request): | 573 | async def handle_get_db_usage(self, request): |
| 573 | return {"usage": await self.db.get_usage()} | 574 | return {"usage": await self.db.get_usage()} |
| 574 | 575 | ||
| 576 | @permissions(DB_ADMIN_PERM) | ||
| 577 | async def handle_get_db_query_columns(self, request): | ||
| 578 | return {"columns": await self.db.get_query_columns()} | ||
| 579 | |||
| 575 | # The authentication API is always allowed | 580 | # The authentication API is always allowed |
| 576 | async def handle_auth(self, request): | 581 | async def handle_auth(self, request): |
| 577 | username = str(request["username"]) | 582 | username = str(request["username"]) |
diff --git a/bitbake/lib/hashserv/sqlalchemy.py b/bitbake/lib/hashserv/sqlalchemy.py index 818b51951b..cee04bffb0 100644 --- a/bitbake/lib/hashserv/sqlalchemy.py +++ b/bitbake/lib/hashserv/sqlalchemy.py | |||
| @@ -415,3 +415,13 @@ class Database(object): | |||
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | return usage | 417 | return usage |
| 418 | |||
| 419 | async def get_query_columns(self): | ||
| 420 | columns = set() | ||
| 421 | for table in (UnihashesV2, OuthashesV2): | ||
| 422 | for c in table.__table__.columns: | ||
| 423 | if not isinstance(c.type, Text): | ||
| 424 | continue | ||
| 425 | columns.add(c.key) | ||
| 426 | |||
| 427 | return list(columns) | ||
diff --git a/bitbake/lib/hashserv/sqlite.py b/bitbake/lib/hashserv/sqlite.py index dfdccbbaa0..f65036be93 100644 --- a/bitbake/lib/hashserv/sqlite.py +++ b/bitbake/lib/hashserv/sqlite.py | |||
| @@ -399,3 +399,10 @@ class Database(object): | |||
| 399 | "rows": cursor.fetchone()[0], | 399 | "rows": cursor.fetchone()[0], |
| 400 | } | 400 | } |
| 401 | return usage | 401 | return usage |
| 402 | |||
| 403 | async def get_query_columns(self): | ||
| 404 | columns = set() | ||
| 405 | for name, typ, _ in UNIHASH_TABLE_DEFINITION + OUTHASH_TABLE_DEFINITION: | ||
| 406 | if typ.startswith("TEXT"): | ||
| 407 | columns.add(name) | ||
| 408 | return list(columns) | ||
diff --git a/bitbake/lib/hashserv/tests.py b/bitbake/lib/hashserv/tests.py index 9d5bec2454..fc69acaf7c 100644 --- a/bitbake/lib/hashserv/tests.py +++ b/bitbake/lib/hashserv/tests.py | |||
| @@ -776,6 +776,14 @@ class HashEquivalenceCommonTests(object): | |||
| 776 | self.assertIn("rows", usage[name]) | 776 | self.assertIn("rows", usage[name]) |
| 777 | self.assertTrue(isinstance(usage[name]["rows"], int)) | 777 | self.assertTrue(isinstance(usage[name]["rows"], int)) |
| 778 | 778 | ||
| 779 | def test_get_db_query_columns(self): | ||
| 780 | columns = self.client.get_db_query_columns() | ||
| 781 | |||
| 782 | self.assertTrue(isinstance(columns, list)) | ||
| 783 | self.assertTrue(len(columns) > 0) | ||
| 784 | |||
| 785 | for col in columns: | ||
| 786 | self.client.remove({col: ""}) | ||
| 779 | 787 | ||
| 780 | class TestHashEquivalenceUnixServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase): | 788 | class TestHashEquivalenceUnixServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase): |
| 781 | def get_server_addr(self, server_idx): | 789 | def get_server_addr(self, server_idx): |
