kaqing 2.0.50__tar.gz → 2.0.51__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kaqing-2.0.50 → kaqing-2.0.51}/PKG-INFO +1 -1
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/cql/cql_completions.py +2 -4
- kaqing-2.0.51/adam/commands/cql/cql_table_completer.py +8 -0
- kaqing-2.0.51/adam/commands/postgres/psql_completions.py +10 -0
- kaqing-2.0.51/adam/commands/postgres/psql_table_completer.py +11 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/preview_table.py +1 -1
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/repl.py +1 -2
- kaqing-2.0.51/adam/sql/sql_completer.py +403 -0
- kaqing-2.0.51/adam/sql/term_completer.py +66 -0
- kaqing-2.0.51/adam/version.py +5 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/kaqing.egg-info/PKG-INFO +1 -1
- {kaqing-2.0.50 → kaqing-2.0.51}/kaqing.egg-info/SOURCES.txt +1 -2
- {kaqing-2.0.50 → kaqing-2.0.51}/setup.py +1 -1
- kaqing-2.0.50/adam/commands/cql/cql_table_completer.py +0 -16
- kaqing-2.0.50/adam/commands/postgres/psql_completions.py +0 -11
- kaqing-2.0.50/adam/commands/postgres/psql_table_completer.py +0 -18
- kaqing-2.0.50/adam/sql/any_completer.py +0 -84
- kaqing-2.0.50/adam/sql/sql_completer.py +0 -53
- kaqing-2.0.50/adam/sql/table_name_completer.py +0 -17
- kaqing-2.0.50/adam/version.py +0 -5
- {kaqing-2.0.50 → kaqing-2.0.51}/README +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/app_session.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/apps.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/batch.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/check.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/check_context.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/check_result.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/check_utils.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/compactionstats.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/cpu.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/disk.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/gossip.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/issue.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/memory.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/checks/status.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/cli.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/cli_group.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/column.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/columns.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/compactions.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/cpu.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/dir_data.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/dir_snapshots.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/gossip.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/host_id.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/memory.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/node_address.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/node_load.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/node_owns.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/node_status.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/node_tokens.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/node_utils.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/pod_name.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/volume_cassandra.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/columns/volume_root.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/alter_tables.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/app.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/app_ping.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/bash.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/cd.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/check.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/cli_commands.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/command.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/command_helpers.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/commands_utils.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/cp.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/cql/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/cql/cql_utils.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/cql/cqlsh.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/code_start.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/code_stop.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/code_utils.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/deploy.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/deploy_frontend.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/deploy_pg_agent.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/deploy_pod.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/deploy_utils.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/undeploy.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/undeploy_frontend.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/undeploy_pg_agent.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/deploy/undeploy_pod.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/describe/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/describe/describe.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/describe/describe_keyspace.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/describe/describe_keyspaces.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/describe/describe_table.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/describe/describe_tables.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/devices.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/exit.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/help.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/issues.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/login.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/logs.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/ls.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/medusa/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/medusa/medusa.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/medusa/medusa_backup.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/medusa/medusa_restore.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/medusa/medusa_show_backupjobs.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/medusa/medusa_show_restorejobs.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/nodetool.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/nodetool_commands.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/param_get.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/param_set.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/postgres/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/postgres/postgres.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/postgres/postgres_ls.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/postgres/postgres_preview.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/postgres/postgres_session.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/postgres/postgres_utils.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/pwd.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_forward.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_forward_stop.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_restart.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_run_abort.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_runs.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_runs_abort.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_schedule_activate.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_schedule_start.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_schedule_stop.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_schedules.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_session.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/reaper/reaper_status.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/repair/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/repair/repair.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/repair/repair_log.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/repair/repair_run.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/repair/repair_scan.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/repair/repair_stop.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/report.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/restart.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/rollout.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/shell.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_adam.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_app_actions.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_app_id.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_app_queues.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_cassandra_status.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_cassandra_version.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_commands.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_login.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_params.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_processes.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_repairs.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/show/show_storage.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/commands/watch.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/config.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/embedded_apps.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/embedded_params.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/cassandra_clusters.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/cassandra_nodes.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/config_maps.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/custom_resources.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/deployment.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/ingresses.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/jobs.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/kube_context.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/pods.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/secrets.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/service_accounts.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/services.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/statefulsets.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/k8s_utils/volumes.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/log.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/pod_exec_result.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/repl_commands.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/repl_session.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/repl_state.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sql/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sql/sql_utils.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sso/__init__.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sso/authenticator.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sso/authn_ad.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sso/authn_okta.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sso/cred_cache.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sso/id_token.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sso/idp.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sso/idp_login.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sso/idp_session.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/sso/sso_config.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/adam/utils.py +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/kaqing.egg-info/dependency_links.txt +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/kaqing.egg-info/entry_points.txt +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/kaqing.egg-info/top_level.txt +0 -0
- {kaqing-2.0.50 → kaqing-2.0.51}/setup.cfg +0 -0
@@ -1,13 +1,11 @@
|
|
1
|
-
from adam.commands.cql.cql_table_completer import CqlTableNameCompleter
|
2
1
|
from adam.commands.cql.cql_utils import table_names
|
3
2
|
from adam.repl_state import ReplState
|
4
3
|
from adam.sql.sql_completer import SqlCompleter
|
5
4
|
|
6
5
|
def cql_completions(state: ReplState) -> dict[str, any]:
|
7
|
-
table_name_completer = CqlTableNameCompleter(table_names(state))
|
8
6
|
return {
|
9
7
|
'describe': {
|
10
8
|
'keyspaces': None,
|
11
|
-
'table':
|
9
|
+
'table': {t: None for t in table_names(state)},
|
12
10
|
'tables': None},
|
13
|
-
} | SqlCompleter.completions(
|
11
|
+
} | SqlCompleter.completions(lambda: table_names(state))
|
@@ -0,0 +1,8 @@
|
|
1
|
+
from adam.sql.term_completer import TermCompleter
|
2
|
+
|
3
|
+
class CqlTableNameCompleter(TermCompleter):
|
4
|
+
def __init__(self, tables: list[str], ignore_case: bool = True):
|
5
|
+
super().__init__(tables, ignore_case=ignore_case)
|
6
|
+
|
7
|
+
def __repr__(self) -> str:
|
8
|
+
return "CqlTableCompleter(%r)" % (len(self.words))
|
@@ -0,0 +1,10 @@
|
|
1
|
+
from adam.commands.postgres.postgres_utils import pg_table_names
|
2
|
+
from adam.sql.sql_completer import SqlCompleter
|
3
|
+
|
4
|
+
def psql_completions(ns: str, pg_path: str):
|
5
|
+
return {
|
6
|
+
'\h': None,
|
7
|
+
'\d': None,
|
8
|
+
'\dt': None,
|
9
|
+
'\du': None
|
10
|
+
} | SqlCompleter.completions(lambda: pg_table_names(ns, pg_path))
|
@@ -0,0 +1,11 @@
|
|
1
|
+
from adam.commands.postgres.postgres_utils import pg_table_names
|
2
|
+
from adam.sql.term_completer import TermCompleter
|
3
|
+
|
4
|
+
class PsqlTableNameCompleter(TermCompleter):
|
5
|
+
def __init__(self, namespace: str, pg_path: str, ignore_case: bool = True):
|
6
|
+
super().__init__(pg_table_names(namespace, pg_path), ignore_case=ignore_case)
|
7
|
+
self.namespace = namespace
|
8
|
+
self.pg_path = pg_path
|
9
|
+
|
10
|
+
def __repr__(self) -> str:
|
11
|
+
return "PsqlTableCompleter(%r, pg_path=%r)" % (self.namespace, self.pg_path)
|
@@ -3,8 +3,8 @@ import functools
|
|
3
3
|
from adam.commands.command import Command
|
4
4
|
from adam.commands.cql.cql_table_completer import CqlTableNameCompleter
|
5
5
|
from adam.commands.cql.cql_utils import run_cql, table_names, tables
|
6
|
-
from adam.commands.postgres.psql_table_completer import PsqlTableNameCompleter
|
7
6
|
from adam.commands.postgres.postgres_session import PostgresSession
|
7
|
+
from adam.commands.postgres.psql_table_completer import PsqlTableNameCompleter
|
8
8
|
from adam.config import Config
|
9
9
|
from adam.repl_state import ReplState, RequiredState
|
10
10
|
from adam.utils import lines_to_tabular, log, log2
|
@@ -18,7 +18,6 @@ from adam.log import Log
|
|
18
18
|
from adam.repl_commands import ReplCommands
|
19
19
|
from adam.repl_session import ReplSession
|
20
20
|
from adam.repl_state import ReplState
|
21
|
-
from adam.sql.sql_completer import SqlCompleter
|
22
21
|
from adam.utils import deep_merge_dicts, deep_sort_dict, lines_to_tabular, log2
|
23
22
|
from adam.apps import Apps
|
24
23
|
from . import __version__
|
@@ -109,7 +108,7 @@ def enter_repl(state: ReplState):
|
|
109
108
|
log2(f'Timing auto-completion-calc {cmd.command()}: {time.time() - s1:.2f}')
|
110
109
|
|
111
110
|
# print(json.dumps(completions, indent=4))
|
112
|
-
completer =
|
111
|
+
completer = NestedCompleter.from_nested_dict(completions)
|
113
112
|
|
114
113
|
cmd = session.prompt(prompt_msg(), completer=completer, key_bindings=kb)
|
115
114
|
s0 = time.time()
|
@@ -0,0 +1,403 @@
|
|
1
|
+
from typing import Callable, Iterable
|
2
|
+
from prompt_toolkit.completion import CompleteEvent, Completer, Completion
|
3
|
+
from prompt_toolkit.document import Document
|
4
|
+
import sqlparse
|
5
|
+
from sqlparse.sql import Statement, Token
|
6
|
+
from sqlparse import tokens as T
|
7
|
+
|
8
|
+
from adam.sql.term_completer import TermCompleter
|
9
|
+
|
10
|
+
class SqlCompleter(Completer):
|
11
|
+
def __init__(self, tables: Callable[[], list[str]], dml: str = None, debug = False):
|
12
|
+
super().__init__()
|
13
|
+
self.dml = dml
|
14
|
+
self.tables = tables
|
15
|
+
self.debug = debug
|
16
|
+
|
17
|
+
def get_completions(
|
18
|
+
self, document: Document, complete_event: CompleteEvent
|
19
|
+
) -> Iterable[Completion]:
|
20
|
+
text = document.text_before_cursor.lstrip()
|
21
|
+
if self.dml:
|
22
|
+
state = f'{self.dml}_'
|
23
|
+
text = f'{self.dml} {text}'
|
24
|
+
|
25
|
+
completer = None
|
26
|
+
stmts = sqlparse.parse(text)
|
27
|
+
if not stmts:
|
28
|
+
completer = TermCompleter(['select', 'insert', 'delete', 'update'])
|
29
|
+
else:
|
30
|
+
statement: Statement = stmts[0]
|
31
|
+
state = self.traverse_tokens(text, statement.tokens)
|
32
|
+
if self.debug:
|
33
|
+
print('\n =>', state)
|
34
|
+
if state == 'dml_incomplete':
|
35
|
+
completer = TermCompleter(['select', 'insert', 'delete', 'update'])
|
36
|
+
|
37
|
+
elif state == 'select_':
|
38
|
+
completer = TermCompleter(['*'])
|
39
|
+
elif state == 'select_a':
|
40
|
+
completer = TermCompleter(['from'])
|
41
|
+
elif state == 'select_a,':
|
42
|
+
completer = TermCompleter(['*'])
|
43
|
+
elif state == 'select_a_':
|
44
|
+
completer = TermCompleter(['from'])
|
45
|
+
elif state == "select_a_from_":
|
46
|
+
completer = TermCompleter(self.tables())
|
47
|
+
elif state == "select_a_from_x_":
|
48
|
+
completer = TermCompleter(['where', 'group', 'limit'])
|
49
|
+
elif state == "select_a_from_x,":
|
50
|
+
completer = TermCompleter(self.tables())
|
51
|
+
elif state == "select_a_from_x_where_":
|
52
|
+
completer = TermCompleter(['id'])
|
53
|
+
elif state == "select_a_from_x_where_id":
|
54
|
+
completer = TermCompleter(['=', '<', '<=', '>', '>=', '<>', 'like'])
|
55
|
+
elif state == "select_a_from_x_where_id=":
|
56
|
+
completer = TermCompleter(["'"])
|
57
|
+
elif state == "select_a_from_x_where_id=v_":
|
58
|
+
completer = TermCompleter(['and', 'or', 'group', 'limit'])
|
59
|
+
elif state == "select_a_from_x_where_id=v_limit_":
|
60
|
+
completer = TermCompleter(['1'])
|
61
|
+
elif state == "select_a_from_x_group_":
|
62
|
+
completer = TermCompleter(['by'])
|
63
|
+
elif state == "select_a_from_x_group_by_":
|
64
|
+
completer = TermCompleter(['id'])
|
65
|
+
elif state == "select_a_from_x_group_by_a,":
|
66
|
+
completer = TermCompleter(['id'])
|
67
|
+
elif state == "select_a_from_x_group_by_a_":
|
68
|
+
completer = TermCompleter(['limit'])
|
69
|
+
elif state == "select_a_from_x_group_by_a_limit_":
|
70
|
+
completer = TermCompleter(['1'])
|
71
|
+
|
72
|
+
elif state == "insert_":
|
73
|
+
completer = TermCompleter(['into'])
|
74
|
+
elif state == "insert_into_":
|
75
|
+
completer = TermCompleter(self.tables())
|
76
|
+
elif state == "insert_into_x_":
|
77
|
+
completer = TermCompleter(['values'])
|
78
|
+
elif state == "insert_into_x(":
|
79
|
+
completer = TermCompleter(['id'])
|
80
|
+
elif state == "insert_into_x(a,":
|
81
|
+
completer = TermCompleter(['id'])
|
82
|
+
elif state == "insert_into_x(a)_":
|
83
|
+
completer = TermCompleter(['values('])
|
84
|
+
elif state == "insert_into_x_values":
|
85
|
+
completer = TermCompleter(['('])
|
86
|
+
elif state == "insert_into_x_values(":
|
87
|
+
completer = TermCompleter(["'"])
|
88
|
+
|
89
|
+
elif state == "update_":
|
90
|
+
completer = TermCompleter(self.tables())
|
91
|
+
elif state == "update_x_":
|
92
|
+
completer = TermCompleter(['set'])
|
93
|
+
elif state in ["update_x_set_", "update_x_set_a=v,"]:
|
94
|
+
completer = TermCompleter(['id'])
|
95
|
+
elif state == "update_x_set_a":
|
96
|
+
completer = TermCompleter(['='])
|
97
|
+
elif state == "update_x_set_a=":
|
98
|
+
completer = TermCompleter(["'"])
|
99
|
+
elif state == "update_x_set_a=v_":
|
100
|
+
completer = TermCompleter(['where'])
|
101
|
+
elif state == "update_x_set_a=v_where_":
|
102
|
+
completer = TermCompleter(['id'])
|
103
|
+
elif state == "update_x_set_a=v_where_id":
|
104
|
+
completer = TermCompleter(['='])
|
105
|
+
elif state == "update_x_set_a=v_where_id=v_":
|
106
|
+
completer = TermCompleter(['and', 'or'])
|
107
|
+
|
108
|
+
elif state == "delete_":
|
109
|
+
completer = TermCompleter(['from'])
|
110
|
+
elif state == "delete_from_":
|
111
|
+
completer = TermCompleter(self.tables())
|
112
|
+
elif state == "delete_from_x_":
|
113
|
+
completer = TermCompleter(['where'])
|
114
|
+
elif state == "delete_from_x_where_":
|
115
|
+
completer = TermCompleter(['id'])
|
116
|
+
elif state == "delete_from_x_where_id":
|
117
|
+
completer = TermCompleter(['='])
|
118
|
+
elif state == "delete_from_x_where_id=":
|
119
|
+
completer = TermCompleter(["'"])
|
120
|
+
elif state == "delete_from_x_where_id=v_":
|
121
|
+
completer = TermCompleter(['and', 'or'])
|
122
|
+
|
123
|
+
if completer:
|
124
|
+
for c in completer.get_completions(document, complete_event):
|
125
|
+
yield c
|
126
|
+
|
127
|
+
def traverse_tokens(self, text: str, tokens: list[Token], state: str = None, indent=0):
|
128
|
+
# state: str = None
|
129
|
+
for token in tokens:
|
130
|
+
if self.debug:
|
131
|
+
if token.ttype == T.Whitespace:
|
132
|
+
print('_ ', end='')
|
133
|
+
elif token.ttype in [T.DML, T.Wildcard, T.Punctuation]:
|
134
|
+
print(f'{token.value} ', end='')
|
135
|
+
elif token.ttype:
|
136
|
+
tks = str(token.ttype).split('.')
|
137
|
+
typ = tks[len(tks) - 1]
|
138
|
+
if ' ' in token.value:
|
139
|
+
print(f'"{token.value}:{typ}" ', end='')
|
140
|
+
else:
|
141
|
+
print(f'{token.value}:{typ} ', end='')
|
142
|
+
# print(" " * indent + f"Token: {token.value}, Type: {token.ttype}@{token.ttype.__class__}")
|
143
|
+
node: str = None
|
144
|
+
if token.is_group:
|
145
|
+
state = self.traverse_tokens(text, token.tokens, state, indent + 1)
|
146
|
+
else:
|
147
|
+
if not state:
|
148
|
+
if token.ttype == T.Keyword.DML and token.value.lower() == 'select':
|
149
|
+
state = 'select'
|
150
|
+
if token.ttype == T.Keyword.DML and token.value.lower() == 'insert':
|
151
|
+
state = 'insert'
|
152
|
+
if token.ttype == T.Keyword.DML and token.value.lower() == 'update':
|
153
|
+
state = 'update'
|
154
|
+
if token.ttype == T.Keyword.DML and token.value.lower() == 'delete':
|
155
|
+
state = 'delete'
|
156
|
+
elif token.ttype == T.Name:
|
157
|
+
state = 'dml_incomplete'
|
158
|
+
|
159
|
+
elif state == 'select':
|
160
|
+
if token.ttype == T.Text.Whitespace:
|
161
|
+
state = 'select_'
|
162
|
+
elif state == 'select_':
|
163
|
+
if token.ttype == T.Name or token.ttype == T.Wildcard:
|
164
|
+
state = 'select_a'
|
165
|
+
elif state == 'select_a':
|
166
|
+
if token.ttype == T.Text.Whitespace:
|
167
|
+
state = 'select_a_'
|
168
|
+
elif token.ttype == T.Punctuation and token.value == ',':
|
169
|
+
state = 'select_a,'
|
170
|
+
elif state == 'select_a,':
|
171
|
+
if token.ttype == T.Name or token.ttype == T.Wildcard:
|
172
|
+
state = 'select_a'
|
173
|
+
elif state == 'select_a_':
|
174
|
+
if token.ttype == T.Keyword and token.value.lower() == 'from':
|
175
|
+
state = 'select_a_from'
|
176
|
+
elif state == 'select_a_from':
|
177
|
+
if token.ttype == T.Text.Whitespace:
|
178
|
+
state = 'select_a_from_'
|
179
|
+
elif state == 'select_a_from_':
|
180
|
+
if token.ttype == T.Name:
|
181
|
+
state = 'select_a_from_x'
|
182
|
+
elif state == 'select_a_from_x':
|
183
|
+
if token.ttype == T.Text.Whitespace:
|
184
|
+
state = 'select_a_from_x_'
|
185
|
+
elif token.ttype == T.Punctuation and token.value == ',':
|
186
|
+
state = 'select_a_from_x,'
|
187
|
+
elif state == 'select_a_from_x,':
|
188
|
+
if token.ttype == T.Name:
|
189
|
+
state = 'select_a_from_x'
|
190
|
+
elif state == 'select_a_from_x_':
|
191
|
+
if token.ttype == T.Keyword and token.value.lower() == 'where':
|
192
|
+
state = 'select_a_from_x_where'
|
193
|
+
elif token.ttype == T.Keyword and token.value.lower() == 'limit':
|
194
|
+
state = 'select_a_from_x_where_id=v_limit'
|
195
|
+
elif token.ttype == T.Keyword and token.value.lower() == 'group':
|
196
|
+
state = 'select_a_from_x_group'
|
197
|
+
elif token.ttype == T.Keyword and token.value.lower() == 'group by':
|
198
|
+
state = 'select_a_from_x_group_by'
|
199
|
+
elif state == 'select_a_from_x_where':
|
200
|
+
if token.ttype == T.Text.Whitespace:
|
201
|
+
state = 'select_a_from_x_where_'
|
202
|
+
elif state == 'select_a_from_x_where_':
|
203
|
+
if token.ttype == T.Name:
|
204
|
+
state = 'select_a_from_x_where_id'
|
205
|
+
elif state == 'select_a_from_x_where_id':
|
206
|
+
if token.ttype == T.Operator.Comparison:
|
207
|
+
state = 'select_a_from_x_where_id='
|
208
|
+
elif state == 'select_a_from_x_where_id=':
|
209
|
+
if token.ttype in [T.Literal.String.Single, T.Name]:
|
210
|
+
state = 'select_a_from_x_where_id=v'
|
211
|
+
elif state == 'select_a_from_x_where_id=v':
|
212
|
+
if token.ttype == T.Text.Whitespace:
|
213
|
+
state = 'select_a_from_x_where_id=v_'
|
214
|
+
elif state == 'select_a_from_x_where_id=v_':
|
215
|
+
if token.ttype == T.Keyword and token.value.lower() in ['and', 'or']:
|
216
|
+
state = 'select_a_from_x_where'
|
217
|
+
elif token.ttype == T.Keyword and token.value.lower() == 'group':
|
218
|
+
state = 'select_a_from_x_group'
|
219
|
+
elif token.ttype == T.Keyword and token.value.lower() == 'limit':
|
220
|
+
state = 'select_a_from_x_where_id=v_limit'
|
221
|
+
elif state == 'select_a_from_x_group':
|
222
|
+
if token.ttype == T.Text.Whitespace:
|
223
|
+
state = 'select_a_from_x_group_'
|
224
|
+
elif state == 'select_a_from_x_group_':
|
225
|
+
if token.ttype == T.Keyword and token.value.lower() == 'by':
|
226
|
+
state = 'select_a_from_x_group_by'
|
227
|
+
elif state == 'select_a_from_x_group_by':
|
228
|
+
if token.ttype == T.Text.Whitespace:
|
229
|
+
state = 'select_a_from_x_group_by_'
|
230
|
+
elif state == 'select_a_from_x_group_by_':
|
231
|
+
if token.ttype == T.Name:
|
232
|
+
state = 'select_a_from_x_group_by_a'
|
233
|
+
elif state == 'select_a_from_x_group_by_a':
|
234
|
+
if token.ttype == T.Text.Whitespace:
|
235
|
+
state = 'select_a_from_x_group_by_a_'
|
236
|
+
elif token.ttype == T.Punctuation and token.value == ',':
|
237
|
+
state = 'select_a_from_x_group_by_a,'
|
238
|
+
elif state == 'select_a_from_x_group_by_a,':
|
239
|
+
if token.ttype == T.Name:
|
240
|
+
state = 'select_a_from_x_group_by_a'
|
241
|
+
elif state == 'select_a_from_x_group_by_a_':
|
242
|
+
if token.ttype == T.Keyword and token.value.lower() == 'limit':
|
243
|
+
state = 'select_a_from_x_where_id=v_limit'
|
244
|
+
elif state == 'select_a_from_x_where_id=v_limit':
|
245
|
+
if token.ttype == T.Text.Whitespace:
|
246
|
+
state = 'select_a_from_x_where_id=v_limit_'
|
247
|
+
|
248
|
+
elif state == 'insert':
|
249
|
+
if token.ttype == T.Text.Whitespace:
|
250
|
+
state = 'insert_'
|
251
|
+
elif state == 'insert_':
|
252
|
+
if token.ttype == T.Keyword and token.value.lower() == 'into':
|
253
|
+
state = 'insert_into'
|
254
|
+
elif state == 'insert_into':
|
255
|
+
if token.ttype == T.Text.Whitespace:
|
256
|
+
state = 'insert_into_'
|
257
|
+
elif state == 'insert_into_':
|
258
|
+
if token.ttype == T.Name:
|
259
|
+
state = 'insert_into_x'
|
260
|
+
elif state == 'insert_into_x':
|
261
|
+
if token.ttype == T.Text.Whitespace:
|
262
|
+
state = 'insert_into_x_'
|
263
|
+
elif token.ttype == T.Punctuation and token.value == '(':
|
264
|
+
state = 'insert_into_x('
|
265
|
+
elif state == 'insert_into_x_':
|
266
|
+
if token.ttype == T.Punctuation and token.value == '(':
|
267
|
+
state = 'insert_into_x('
|
268
|
+
elif token.ttype == T.Keyword and token.value.lower() == 'values':
|
269
|
+
state = 'insert_into_x_values'
|
270
|
+
elif state == 'insert_into_x(':
|
271
|
+
if token.ttype == T.Name:
|
272
|
+
state = 'insert_into_x(a'
|
273
|
+
elif state == 'insert_into_x(a':
|
274
|
+
if token.ttype == T.Punctuation and token.value == ',':
|
275
|
+
state = 'insert_into_x(a,'
|
276
|
+
elif token.ttype == T.Punctuation and token.value == ')':
|
277
|
+
state = 'insert_into_x(a)'
|
278
|
+
elif state == 'insert_into_x(a,':
|
279
|
+
if token.ttype == T.Name:
|
280
|
+
state = 'insert_into_x(a'
|
281
|
+
elif state == 'insert_into_x(a)':
|
282
|
+
if token.ttype == T.Text.Whitespace:
|
283
|
+
state = 'insert_into_x(a)_'
|
284
|
+
elif state == 'insert_into_x(a)_':
|
285
|
+
if token.ttype == T.Keyword and token.value.lower() == 'values':
|
286
|
+
state = 'insert_into_x_values'
|
287
|
+
elif state == 'insert_into_x_values':
|
288
|
+
if token.ttype == T.Punctuation and token.value == '(':
|
289
|
+
state = 'insert_into_x_values('
|
290
|
+
elif state == 'insert_into_x_values(':
|
291
|
+
if token.ttype in [T.Literal.String.Single, T.Name]:
|
292
|
+
state = 'insert_into_x_values(v'
|
293
|
+
elif state == 'insert_into_x_values(v':
|
294
|
+
if token.ttype == T.Punctuation and token.value == ',':
|
295
|
+
state = 'insert_into_x_values(v,'
|
296
|
+
elif token.ttype == T.Punctuation and token.value == ')':
|
297
|
+
state = 'insert_into_x_values(v)'
|
298
|
+
elif state == 'insert_into_x_values(v,':
|
299
|
+
if token.ttype in [T.Literal.String.Single, T.Name]:
|
300
|
+
state = 'insert_into_x_values(v'
|
301
|
+
|
302
|
+
elif state == 'update':
|
303
|
+
if token.ttype == T.Text.Whitespace:
|
304
|
+
state = 'update_'
|
305
|
+
elif state == 'update_':
|
306
|
+
if token.ttype == T.Name:
|
307
|
+
state = 'update_x'
|
308
|
+
elif state == 'update_x':
|
309
|
+
if token.ttype == T.Text.Whitespace:
|
310
|
+
state = 'update_x_'
|
311
|
+
elif state == 'update_x_':
|
312
|
+
if token.ttype == T.Keyword and token.value.lower() == 'set':
|
313
|
+
state = 'update_x_set'
|
314
|
+
elif state == 'update_x_set':
|
315
|
+
if token.ttype == T.Text.Whitespace:
|
316
|
+
state = 'update_x_set_'
|
317
|
+
elif state == 'update_x_set_':
|
318
|
+
if token.ttype == T.Name:
|
319
|
+
state = 'update_x_set_a'
|
320
|
+
elif state == 'update_x_set_a':
|
321
|
+
if token.ttype == T.Operator.Comparison:
|
322
|
+
state = 'update_x_set_a='
|
323
|
+
elif state == 'update_x_set_a=':
|
324
|
+
if token.ttype in [T.Literal.String.Single, T.Name]:
|
325
|
+
state = 'update_x_set_a=v'
|
326
|
+
elif state == 'update_x_set_a=v':
|
327
|
+
if token.ttype == T.Punctuation and token.value == ',':
|
328
|
+
state = 'update_x_set_a=v,'
|
329
|
+
elif token.ttype == T.Text.Whitespace:
|
330
|
+
state = 'update_x_set_a=v_'
|
331
|
+
elif state == 'update_x_set_a=v,':
|
332
|
+
if token.ttype == T.Name:
|
333
|
+
state = 'update_x_set_a'
|
334
|
+
elif state == 'update_x_set_a=v_':
|
335
|
+
if token.ttype == T.Punctuation and token.value == ',':
|
336
|
+
state = 'update_x_set_a=v,'
|
337
|
+
elif token.ttype == T.Keyword and token.value.lower() == 'where':
|
338
|
+
state = 'update_x_set_a=v_where'
|
339
|
+
elif state == 'update_x_set_a=v_where':
|
340
|
+
if token.ttype == T.Text.Whitespace:
|
341
|
+
state = 'update_x_set_a=v_where_'
|
342
|
+
elif state == 'update_x_set_a=v_where_':
|
343
|
+
if token.ttype == T.Name:
|
344
|
+
state = 'update_x_set_a=v_where_id'
|
345
|
+
elif state == 'update_x_set_a=v_where_id':
|
346
|
+
if token.ttype == T.Operator.Comparison:
|
347
|
+
state = 'update_x_set_a=v_where_id='
|
348
|
+
elif state == 'update_x_set_a=v_where_id=':
|
349
|
+
if token.ttype in [T.Literal.String.Single, T.Name]:
|
350
|
+
state = 'update_x_set_a=v_where_id=v'
|
351
|
+
elif state == 'update_x_set_a=v_where_id=v':
|
352
|
+
if token.ttype == T.Text.Whitespace:
|
353
|
+
state = 'update_x_set_a=v_where_id=v_'
|
354
|
+
elif state == 'update_x_set_a=v_where_id=v_':
|
355
|
+
if token.ttype == T.Keyword and token.value.lower() in ['and', 'or']:
|
356
|
+
state = 'update_x_set_a=v_where'
|
357
|
+
|
358
|
+
elif state == 'delete':
|
359
|
+
if token.ttype == T.Text.Whitespace:
|
360
|
+
state = 'delete_'
|
361
|
+
elif state == 'delete_':
|
362
|
+
if token.ttype == T.Keyword and token.value.lower() == 'from':
|
363
|
+
state = 'delete_from'
|
364
|
+
elif state == 'delete_from':
|
365
|
+
if token.ttype == T.Text.Whitespace:
|
366
|
+
state = 'delete_from_'
|
367
|
+
elif state == 'delete_from_':
|
368
|
+
if token.ttype == T.Name:
|
369
|
+
state = 'delete_from_x'
|
370
|
+
elif state == 'delete_from_x':
|
371
|
+
if token.ttype == T.Text.Whitespace:
|
372
|
+
state = 'delete_from_x_'
|
373
|
+
elif state == 'delete_from_x_':
|
374
|
+
if token.ttype == T.Keyword and token.value.lower() == 'where':
|
375
|
+
state = 'delete_from_x_where'
|
376
|
+
elif state == 'delete_from_x_where':
|
377
|
+
if token.ttype == T.Text.Whitespace:
|
378
|
+
state = 'delete_from_x_where_'
|
379
|
+
elif state == 'delete_from_x_where_':
|
380
|
+
if token.ttype == T.Name:
|
381
|
+
state = 'delete_from_x_where_id'
|
382
|
+
elif state == 'delete_from_x_where_id':
|
383
|
+
if token.ttype == T.Operator.Comparison:
|
384
|
+
state = 'delete_from_x_where_id='
|
385
|
+
elif state == 'delete_from_x_where_id=':
|
386
|
+
if token.ttype in [T.Literal.String.Single, T.Name]:
|
387
|
+
state = 'delete_from_x_where_id=v'
|
388
|
+
elif state == 'delete_from_x_where_id=v':
|
389
|
+
if token.ttype == T.Text.Whitespace:
|
390
|
+
state = 'delete_from_x_where_id=v_'
|
391
|
+
elif state == 'delete_from_x_where_id=v_':
|
392
|
+
if token.ttype == T.Keyword and token.value.lower() in ['and', 'or']:
|
393
|
+
state = 'delete_from_x_where'
|
394
|
+
|
395
|
+
return state
|
396
|
+
|
397
|
+
def completions(table_names: Callable[[], list[str]]):
|
398
|
+
return {
|
399
|
+
'delete': SqlCompleter(table_names, 'delete'),
|
400
|
+
'insert': SqlCompleter(table_names, 'insert'),
|
401
|
+
'select': SqlCompleter(table_names, 'select'),
|
402
|
+
'update': SqlCompleter(table_names, 'update'),
|
403
|
+
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
from typing import Callable, Iterable, List, Mapping, Optional, Pattern, Union
|
2
|
+
|
3
|
+
from prompt_toolkit.completion import CompleteEvent, Completer, Completion, WordCompleter
|
4
|
+
from prompt_toolkit.document import Document
|
5
|
+
from prompt_toolkit.formatted_text import AnyFormattedText
|
6
|
+
|
7
|
+
__all__ = [
|
8
|
+
"TermCompleter",
|
9
|
+
]
|
10
|
+
|
11
|
+
class TermCompleter(WordCompleter):
|
12
|
+
def __init__(
|
13
|
+
self,
|
14
|
+
words: Union[List[str], Callable[[], List[str]]],
|
15
|
+
ignore_case: bool = False,
|
16
|
+
display_dict: Optional[Mapping[str, AnyFormattedText]] = None,
|
17
|
+
meta_dict: Optional[Mapping[str, AnyFormattedText]] = None,
|
18
|
+
WORD: bool = False,
|
19
|
+
sentence: bool = False,
|
20
|
+
match_middle: bool = False,
|
21
|
+
pattern: Optional[Pattern[str]] = None,
|
22
|
+
) -> None:
|
23
|
+
super().__init__(words, ignore_case, display_dict, meta_dict, WORD, sentence, match_middle, pattern)
|
24
|
+
|
25
|
+
def get_completions(
|
26
|
+
self, document: Document, complete_event: CompleteEvent
|
27
|
+
) -> Iterable[Completion]:
|
28
|
+
# Get list of words.
|
29
|
+
words = self.words
|
30
|
+
if callable(words):
|
31
|
+
words = words()
|
32
|
+
|
33
|
+
# Get word/text before cursor.
|
34
|
+
if self.sentence:
|
35
|
+
word_before_cursor = document.text_before_cursor
|
36
|
+
else:
|
37
|
+
word_before_cursor = document.get_word_before_cursor(
|
38
|
+
WORD=self.WORD, pattern=self.pattern
|
39
|
+
)
|
40
|
+
|
41
|
+
if self.ignore_case:
|
42
|
+
word_before_cursor = word_before_cursor.lower()
|
43
|
+
|
44
|
+
def word_matches(word: str) -> bool:
|
45
|
+
"""True when the word before the cursor matches."""
|
46
|
+
if self.ignore_case:
|
47
|
+
word = word.lower()
|
48
|
+
|
49
|
+
if word_before_cursor in ['(', ',', '=']:
|
50
|
+
return True
|
51
|
+
|
52
|
+
if self.match_middle:
|
53
|
+
return word_before_cursor in word
|
54
|
+
else:
|
55
|
+
return word.startswith(word_before_cursor)
|
56
|
+
|
57
|
+
for a in words:
|
58
|
+
if word_matches(a):
|
59
|
+
display = self.display_dict.get(a, a)
|
60
|
+
display_meta = self.meta_dict.get(a, "")
|
61
|
+
yield Completion(
|
62
|
+
a,
|
63
|
+
-len(word_before_cursor),
|
64
|
+
display=display,
|
65
|
+
display_meta=display_meta,
|
66
|
+
)
|
@@ -166,10 +166,9 @@ adam/k8s_utils/services.py
|
|
166
166
|
adam/k8s_utils/statefulsets.py
|
167
167
|
adam/k8s_utils/volumes.py
|
168
168
|
adam/sql/__init__.py
|
169
|
-
adam/sql/any_completer.py
|
170
169
|
adam/sql/sql_completer.py
|
171
170
|
adam/sql/sql_utils.py
|
172
|
-
adam/sql/
|
171
|
+
adam/sql/term_completer.py
|
173
172
|
adam/sso/__init__.py
|
174
173
|
adam/sso/authenticator.py
|
175
174
|
adam/sso/authn_ad.py
|
@@ -1,16 +0,0 @@
|
|
1
|
-
from adam.sql.table_name_completer import NestedDict, TableNameCompleter
|
2
|
-
|
3
|
-
class CqlTableNameCompleter(TableNameCompleter):
|
4
|
-
def __init__(self, tables: list[str], nested_dict: NestedDict = {}, ignore_case: bool = True):
|
5
|
-
self._tables = tables
|
6
|
-
self.ignore_case = ignore_case
|
7
|
-
self.append_nested_dict(nested_dict)
|
8
|
-
|
9
|
-
def __repr__(self) -> str:
|
10
|
-
return "CqlTableCompleter(%r)" % (len(self._tables))
|
11
|
-
|
12
|
-
def nested(self, data: NestedDict) -> 'TableNameCompleter':
|
13
|
-
return CqlTableNameCompleter(self._tables).append_nested_dict(data)
|
14
|
-
|
15
|
-
def tables(self) -> list[str]:
|
16
|
-
return self._tables
|
@@ -1,11 +0,0 @@
|
|
1
|
-
from adam.commands.postgres.psql_table_completer import PsqlTableNameCompleter
|
2
|
-
from adam.sql.sql_completer import SqlCompleter
|
3
|
-
|
4
|
-
def psql_completions(ns: str, pg_path: str):
|
5
|
-
return {
|
6
|
-
'\h': None,
|
7
|
-
'\d': None,
|
8
|
-
'\dt': None,
|
9
|
-
'\du': None
|
10
|
-
} | SqlCompleter.completions(PsqlTableNameCompleter(ns, pg_path))
|
11
|
-
# } | PsqlTableCompleter(ns, pg_path).completions()
|
@@ -1,18 +0,0 @@
|
|
1
|
-
from adam.commands.postgres.postgres_utils import pg_table_names
|
2
|
-
from adam.sql.table_name_completer import NestedDict, TableNameCompleter
|
3
|
-
|
4
|
-
class PsqlTableNameCompleter(TableNameCompleter):
|
5
|
-
def __init__(self, namespace: str, pg_path: str, nested_dict: NestedDict = {}, ignore_case: bool = True):
|
6
|
-
self.namespace = namespace
|
7
|
-
self.pg_path = pg_path
|
8
|
-
self.ignore_case = ignore_case
|
9
|
-
self.append_nested_dict(nested_dict)
|
10
|
-
|
11
|
-
def __repr__(self) -> str:
|
12
|
-
return "PsqlTableCompleter(%r, pg_path=%r)" % (self.namespace, self.pg_path)
|
13
|
-
|
14
|
-
def nested(self, data: NestedDict) -> 'TableNameCompleter':
|
15
|
-
return PsqlTableNameCompleter(self.namespace, self.pg_path).append_nested_dict(data)
|
16
|
-
|
17
|
-
def tables(self) -> list[str]:
|
18
|
-
return pg_table_names(self.namespace, self.pg_path)
|