kaqing 2.0.43__py3-none-any.whl → 2.0.44__py3-none-any.whl

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.
@@ -1,7 +1,7 @@
1
- import functools
2
1
  import click
3
2
 
4
3
  from adam.commands.command import Command
4
+ from adam.commands.postgres.postgres_completions import pg_completions
5
5
  from adam.commands.postgres.postgres_utils import pg_table_names
6
6
  from .postgres_ls import PostgresLs
7
7
  from .postgres_preview import PostgresPreview
@@ -69,20 +69,7 @@ class Postgres(Command):
69
69
  session = PostgresSession(state.namespace, state.pg_path)
70
70
  if session.db:
71
71
  if pg_table_names(state.namespace, state.pg_path):
72
- ts = f'<pg_tables:{state.namespace}:{state.pg_path}>'
73
- leaf = {
74
- '\h': None,
75
- '\d': None,
76
- '\dt': None,
77
- '\du': None,
78
- 'delete': {'from': {ts: {'where': {'id': {'=': None}}}}},
79
- 'insert': {'into': {ts: {'values': None}}},
80
- 'select': {'*': {'from': {ts: {
81
- 'limit': {'1': None},
82
- 'where': {'id': {'=': None}}
83
- }}}},
84
- 'update': {ts: {'set': None}},
85
- }
72
+ leaf = pg_completions(state.namespace, state.pg_path)
86
73
  elif state.pg_path:
87
74
  leaf = {
88
75
  '\h': None,
@@ -0,0 +1,24 @@
1
+ from adam.pg_table_completer import PgTableCompleter
2
+
3
+ def pg_completions(ns: str, pg_path: str):
4
+ table = PgTableCompleter(ns, pg_path)
5
+ return {
6
+ '\h': None,
7
+ '\d': None,
8
+ '\dt': None,
9
+ '\du': None,
10
+ # 'delete': {'from': {ts: {'where': {'id': {'=': None}}}}},
11
+ # 'insert': {'into': {ts: {'values': None}}},
12
+ # 'select': {'*': {'from': {ts: {
13
+ # 'limit': {'1': None},
14
+ # 'where': {'id': {'=': None}}
15
+ # }}}},
16
+ # 'update': {ts: {'set': None}},
17
+ 'delete': {'from': table.nested({'where': {'id': {'=': None}}})},
18
+ 'insert': {'into': table.nested({'values': None})},
19
+ 'select': {'*': {'from': table.nested({
20
+ 'limit': {'1': None},
21
+ 'where': {'id': {'=': None}}
22
+ })}},
23
+ 'update': table.nested({'set': None}),
24
+ }
@@ -0,0 +1,77 @@
1
+ from typing import Any, Dict, Iterable, Mapping, Optional, Set, Union
2
+ from prompt_toolkit.completion import CompleteEvent, Completer, Completion, NestedCompleter, WordCompleter
3
+ from prompt_toolkit.document import Document
4
+
5
+ from adam.commands.postgres.postgres_utils import pg_table_names
6
+
7
+ NestedDict = Mapping[str, Union[Any, Set[str], None, Completer]]
8
+
9
+ class PgTableCompleter(Completer):
10
+ def __init__(self, namespace: str, pg_path: str, nested_dict: NestedDict = None, ignore_case: bool = True):
11
+ self.namespace = namespace
12
+ self.pg_path = pg_path
13
+ self.ignore_case = ignore_case
14
+ if nested_dict:
15
+ self.append_nested_dict(nested_dict)
16
+
17
+ def __repr__(self) -> str:
18
+ return "PgTableCompleter(%r, pg_path=%r)" % (self.namespace, self.pg_path)
19
+
20
+ def nested(self, data: NestedDict):
21
+ return PgTableCompleter(self.namespace, self.pg_path).append_nested_dict(data)
22
+
23
+ def append_nested_dict(self, data: NestedDict) -> "PgTableCompleter":
24
+ options: Dict[str, Optional[Completer]] = {}
25
+ for key, value in data.items():
26
+ if isinstance(value, Completer):
27
+ options[key] = value
28
+ elif isinstance(value, dict):
29
+ options[key] = NestedCompleter.from_nested_dict(value)
30
+ elif isinstance(value, set):
31
+ options[key] = NestedCompleter.from_nested_dict({item: None for item in value})
32
+ else:
33
+ assert value is None
34
+ options[key] = None
35
+
36
+ self.options = options
37
+
38
+ return self
39
+
40
+ def get_completions(
41
+ self, document: Document, complete_event: CompleteEvent
42
+ ) -> Iterable[Completion]:
43
+ text = document.text_before_cursor.lstrip()
44
+ stripped_len = len(document.text_before_cursor) - len(text)
45
+
46
+ if " " in text:
47
+ second_term = None
48
+ tokens = text.split()
49
+ if len(tokens) > 1:
50
+ second_term = tokens[1]
51
+ if second_term:
52
+ completer = self.options.get(second_term)
53
+
54
+ if completer is not None:
55
+ first_term = tokens[0]
56
+ remaining_text = text[len(first_term) :].lstrip()
57
+ move_cursor = len(text) - len(remaining_text) + stripped_len
58
+
59
+ remaining_text = remaining_text[len(second_term) :].lstrip()
60
+ move_cursor = len(text) - len(remaining_text) + stripped_len
61
+
62
+ new_document = Document(
63
+ remaining_text,
64
+ cursor_position=document.cursor_position - move_cursor,
65
+ )
66
+
67
+ for c in completer.get_completions(new_document, complete_event):
68
+ yield c
69
+ else:
70
+ completer = WordCompleter(
71
+ list(self.options.keys()), ignore_case=self.ignore_case
72
+ )
73
+ for c in completer.get_completions(document, complete_event):
74
+ yield c
75
+ else:
76
+ for t in pg_table_names(self.namespace, self.pg_path):
77
+ yield Completion(t)
adam/repl.py CHANGED
@@ -1,4 +1,3 @@
1
- import json
2
1
  import os
3
2
  import re
4
3
  import time
@@ -17,7 +16,6 @@ from adam.k8s_utils.kube_context import KubeContext
17
16
  from adam.k8s_utils.statefulsets import StatefulSets
18
17
  from adam.log import Log
19
18
  from adam.repl_commands import ReplCommands
20
- from adam.repl_completer import CompleterContext, ReplCompleter
21
19
  from adam.repl_session import ReplSession
22
20
  from adam.repl_state import ReplState
23
21
  from adam.utils import deep_merge_dicts, deep_sort_dict, lines_to_tabular, log2
@@ -94,7 +92,7 @@ def enter_repl(state: ReplState):
94
92
  sorted_cmds = sorted(cmd_list, key=lambda cmd: cmd.command())
95
93
  while True:
96
94
  try:
97
- completer = ReplCompleter.from_nested_dict({})
95
+ completer = NestedCompleter.from_nested_dict({})
98
96
  if not state.bash_session:
99
97
  completions = {}
100
98
  # app commands are available only on a: drive
@@ -110,7 +108,7 @@ def enter_repl(state: ReplState):
110
108
  log2(f'Timing auto-completion-calc {cmd.command()}: {time.time() - s1:.2f}')
111
109
 
112
110
  # print(json.dumps(completions, indent=4))
113
- completer = ReplCompleter.from_nested_dict(completions)
111
+ completer = NestedCompleter.from_nested_dict(completions)
114
112
 
115
113
  cmd = session.prompt(prompt_msg(), completer=completer, key_bindings=kb)
116
114
  s0 = time.time()
@@ -154,7 +152,6 @@ def enter_repl(state: ReplState):
154
152
  log2(e)
155
153
  Config().debug(traceback.format_exc())
156
154
  finally:
157
- CompleterContext().reset()
158
155
  Config().clear_wait_log_flag()
159
156
  if Config().get('debugs.timings', False) and 'cmd' in locals() and 's0' in locals():
160
157
  log2(f'Timing command {cmd}: {time.time() - s0:.2f}')
adam/version.py CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
- __version__ = "2.0.43" #: the working version
4
+ __version__ = "2.0.44" #: the working version
5
5
  __release__ = "1.0.0" #: the release version
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kaqing
3
- Version: 2.0.43
3
+ Version: 2.0.44
4
4
  Summary: UNKNOWN
5
5
  Home-page: UNKNOWN
6
6
  License: UNKNOWN
@@ -8,14 +8,14 @@ adam/config.py,sha256=5v8tf98SPnb9Mmn9EzxV1_EbjVrHo1ElkvyHpFMfbzk,2783
8
8
  adam/embedded_apps.py,sha256=lKPx63mKzJbNmwz0rgL4gF76M9fDGxraYTtNAIGnZ_s,419
9
9
  adam/embedded_params.py,sha256=_9tBKpkSzBfzm-s3tUgZs8DcSVBnPA1iumG0ZRCbZIs,4586
10
10
  adam/log.py,sha256=gg5DK52wLPc9cjykeh0WFHyAk1qI3HEpGaAK8W2dzXY,1146
11
+ adam/pg_table_completer.py,sha256=XSG8aT04q4RH2_TqNIyP2zhApDcHH8BQq3DAYUvt5ZM,3140
11
12
  adam/pod_exec_result.py,sha256=nq0xnCNOpUGBSijGF0H-YNrwBc9vUQs4DkvLMIFS5LQ,951
12
- adam/repl.py,sha256=y2jNMYewfo2o36wB9Zknh_MLGzSRHPY0USNU3LOO_7U,7439
13
+ adam/repl.py,sha256=X9ga1iZFIXADQxBXvztFyVNBrfBRxiFLxTUYkm11img,7328
13
14
  adam/repl_commands.py,sha256=aH7xxbsQGrpL9Ozk9QF54iToK6wbDT3Pu9rMyw9sDBY,4719
14
- adam/repl_completer.py,sha256=8OWLEb5UbGwOX5vcJaigR68XxVr9lRBlt8ByVCD7O7Y,2528
15
15
  adam/repl_session.py,sha256=uIogcvWBh7wd8QQ-p_JgLsyJ8YJgINw5vOd6JIsd7Vo,472
16
16
  adam/repl_state.py,sha256=591d7gV6uQSFtm7IWdlIYAHjfAzs9bdvIkwlIAeKddE,7540
17
17
  adam/utils.py,sha256=2DoWsrcaioFFH0-RjT30qelVRPUJqCGTfz_ucfE7F8g,7406
18
- adam/version.py,sha256=eU0CKlIirO6upyKMED0IV0w12H69CmesNmCqalyxx5k,139
18
+ adam/version.py,sha256=WZV5dDTmwvzrae-ufWoxplNySz6Dy2dl8OGMKbrja2k,139
19
19
  adam/checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  adam/checks/check.py,sha256=Qopr3huYcMu2bzQgb99dEUYjFzkjKHRI76S6KA9b9Rk,702
21
21
  adam/checks/check_context.py,sha256=FEHkQ32jY1EDopQ2uYWqy9v7aEEX1orLpJWhopwAlh4,402
@@ -105,7 +105,8 @@ adam/commands/medusa/medusa_restore.py,sha256=MU47bmozrjfGJ6GVkj_OVgLH6Uz_fGh03M
105
105
  adam/commands/medusa/medusa_show_backupjobs.py,sha256=QekHpKezVJdgfa9hOxfgyx-y4D08tmHzyu_AAa8QPR0,1756
106
106
  adam/commands/medusa/medusa_show_restorejobs.py,sha256=wgPonSmC6buDIp3k3WUY-Yu2MyP1xyE3Q_XhvAwpnx4,1651
107
107
  adam/commands/postgres/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
- adam/commands/postgres/postgres.py,sha256=SFy8nj4BCna_MDyrBAujeM7ojGPGJwYRfQPHdJiZ1ow,3475
108
+ adam/commands/postgres/postgres.py,sha256=5WNX4T0S_EsEC6CDCOQWXQG96jfIYQhubedpe2MrNNE,3038
109
+ adam/commands/postgres/postgres_completions.py,sha256=dnnQ7qcw7Cev2ds03q9ydz49oaqsTvjo1GEB5cE2Lzw,857
109
110
  adam/commands/postgres/postgres_ls.py,sha256=HwZTgwGKXUqHX33S8aQPF6FqCrLqtoz4cLyJV2SpoE0,1186
110
111
  adam/commands/postgres/postgres_preview.py,sha256=MLzdEc4mvNj6V1Q8jO5OPznXyYELJHgd35_eQgLlNIU,1274
111
112
  adam/commands/postgres/postgres_session.py,sha256=RcqkCgtA78M-9LKTwG6pp8n9JwjmURXgf1FknIIPl9g,9305
@@ -169,8 +170,8 @@ adam/sso/idp.py,sha256=fvcwUw_URTgsO6ySaqTIw0zQT2qRO1IPSGhf6rPtybo,5804
169
170
  adam/sso/idp_login.py,sha256=QAtCUeDTVWliJy40RK_oac8Vgybr13xH8wzeBoxPaa8,1754
170
171
  adam/sso/idp_session.py,sha256=9BUHNRf70u4rVKrVY1HKPOEmOviXvkjam8WJxmXSKIM,1735
171
172
  adam/sso/sso_config.py,sha256=5N8WZgIJQBtHUy585XLRWKjpU87_v6QluyNK9E27D5s,2459
172
- kaqing-2.0.43.dist-info/METADATA,sha256=BAor1KUFI33TgafSbpLCWAgi0_431eYOpMIDDH1XPqA,132
173
- kaqing-2.0.43.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
174
- kaqing-2.0.43.dist-info/entry_points.txt,sha256=SkzhuQJUWsXOzHeZ5TgQ2c3_g53UGK23zzJU_JTZOZI,39
175
- kaqing-2.0.43.dist-info/top_level.txt,sha256=8_2PZkwBb-xDcnc8a2rAbQeJhXKXskc7zTP7pSPa1fw,5
176
- kaqing-2.0.43.dist-info/RECORD,,
173
+ kaqing-2.0.44.dist-info/METADATA,sha256=wcnMJLsBYC99ZwdqVVCSr8fcXXCavEvv_I-eMPGNJyw,132
174
+ kaqing-2.0.44.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
175
+ kaqing-2.0.44.dist-info/entry_points.txt,sha256=SkzhuQJUWsXOzHeZ5TgQ2c3_g53UGK23zzJU_JTZOZI,39
176
+ kaqing-2.0.44.dist-info/top_level.txt,sha256=8_2PZkwBb-xDcnc8a2rAbQeJhXKXskc7zTP7pSPa1fw,5
177
+ kaqing-2.0.44.dist-info/RECORD,,
adam/repl_completer.py DELETED
@@ -1,74 +0,0 @@
1
- import re
2
-
3
- from typing import Iterable
4
- from prompt_toolkit.completion import CompleteEvent, Completion, NestedCompleter, WordCompleter
5
- from prompt_toolkit.document import Document
6
-
7
- from adam.commands.postgres.postgres_utils import pg_table_names
8
-
9
- class CompleterContext:
10
- # the singleton pattern
11
- def __new__(cls, *args, **kwargs):
12
- if not hasattr(cls, 'instance'): cls.instance = super(CompleterContext, cls).__new__(cls)
13
-
14
- return cls.instance
15
-
16
- def __init__(self):
17
- if not hasattr(self, 'table_resolver'):
18
- self.table_resolver = None
19
- self.tables = []
20
-
21
- def produce(self, word: str):
22
- if match := re.match(r'^<pg_tables:(.*?):(.*?)>$', word):
23
- self.table_resolver = word
24
- self.tables = pg_table_names(match.group(1), match.group(2))
25
-
26
- return self.tables
27
-
28
- return None
29
-
30
- def is_table(self, word: str):
31
- if word in self.tables and self.table_resolver:
32
- return self.table_resolver
33
-
34
- return None
35
-
36
- def reset(self):
37
- self.table_resolver = None
38
- self.tables = []
39
-
40
-
41
- class ReplCompleter(NestedCompleter):
42
- def get_completions(
43
- self, document: Document, complete_event: CompleteEvent
44
- ) -> Iterable[Completion]:
45
- text = document.text_before_cursor.lstrip()
46
- stripped_len = len(document.text_before_cursor) - len(text)
47
-
48
- if " " in text:
49
- first_term = text.split()[0]
50
- completer = self.options.get(first_term)
51
- if table_resolver := CompleterContext().is_table(first_term):
52
- completer = self.options.get(table_resolver)
53
-
54
- if completer is not None:
55
- remaining_text = text[len(first_term) :].lstrip()
56
- move_cursor = len(text) - len(remaining_text) + stripped_len
57
-
58
- new_document = Document(
59
- remaining_text,
60
- cursor_position=document.cursor_position - move_cursor,
61
- )
62
-
63
- for c in completer.get_completions(new_document, complete_event):
64
- if words := CompleterContext().produce(c.text):
65
- for w in words:
66
- yield Completion(w)
67
- else:
68
- yield c
69
- else:
70
- completer = WordCompleter(
71
- list(self.options.keys()), ignore_case=self.ignore_case
72
- )
73
- for c in completer.get_completions(document, complete_event):
74
- yield c