kaqing 2.0.184__py3-none-any.whl → 2.0.214__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.

Potentially problematic release.


This version of kaqing might be problematic. Click here for more details.

Files changed (152) hide show
  1. adam/app_session.py +1 -1
  2. adam/batch.py +15 -15
  3. adam/commands/app/app.py +2 -2
  4. adam/commands/app/show_app_actions.py +1 -1
  5. adam/commands/{show → app}/show_login.py +1 -1
  6. adam/commands/app/utils_app.py +9 -1
  7. adam/commands/audit/audit.py +6 -20
  8. adam/commands/audit/audit_repair_tables.py +1 -1
  9. adam/commands/audit/audit_run.py +1 -1
  10. adam/commands/audit/completions_l.py +15 -0
  11. adam/commands/audit/show_last10.py +0 -1
  12. adam/commands/bash/bash.py +1 -1
  13. adam/commands/bash/utils_bash.py +1 -1
  14. adam/commands/cassandra/download_cassandra_log.py +45 -0
  15. adam/commands/cassandra/restart_cluster.py +47 -0
  16. adam/commands/cassandra/restart_node.py +51 -0
  17. adam/commands/cassandra/restart_nodes.py +47 -0
  18. adam/commands/{rollout.py → cassandra/rollout.py} +1 -1
  19. adam/commands/{show → cassandra}/show_cassandra_repairs.py +5 -3
  20. adam/commands/{show → cassandra}/show_cassandra_status.py +22 -15
  21. adam/commands/cassandra/show_processes.py +50 -0
  22. adam/commands/{show → cassandra}/show_storage.py +10 -8
  23. adam/commands/cli/__init__.py +0 -0
  24. adam/commands/{cli_commands.py → cli/cli_commands.py} +6 -1
  25. adam/commands/{clipboard_copy.py → cli/clipboard_copy.py} +2 -2
  26. adam/commands/{show/show_commands.py → cli/show_cli_commands.py} +2 -2
  27. adam/commands/command.py +22 -9
  28. adam/commands/commands_utils.py +14 -6
  29. adam/commands/config/__init__.py +0 -0
  30. adam/commands/{show → config}/show_params.py +1 -1
  31. adam/commands/{alter_tables.py → cql/alter_tables.py} +1 -1
  32. adam/commands/cql/completions_c.py +29 -0
  33. adam/commands/cql/cqlsh.py +2 -6
  34. adam/commands/cql/utils_cql.py +26 -17
  35. adam/commands/debug/__init__.py +0 -0
  36. adam/commands/debug/debug.py +22 -0
  37. adam/commands/debug/debug_completes.py +35 -0
  38. adam/commands/debug/debug_timings.py +35 -0
  39. adam/commands/debug/show_offloaded_completes.py +45 -0
  40. adam/commands/devices/device.py +30 -4
  41. adam/commands/devices/device_app.py +1 -1
  42. adam/commands/devices/device_export.py +5 -2
  43. adam/commands/devices/device_postgres.py +13 -3
  44. adam/commands/devices/devices.py +1 -1
  45. adam/commands/diag/__init__.py +0 -0
  46. adam/commands/{check.py → diag/check.py} +1 -1
  47. adam/commands/diag/generate_report.py +52 -0
  48. adam/commands/export/completions_x.py +11 -0
  49. adam/commands/export/download_export_session.py +2 -1
  50. adam/commands/export/export.py +0 -16
  51. adam/commands/export/export_databases.py +16 -10
  52. adam/commands/export/export_select.py +8 -33
  53. adam/commands/export/export_sessions.py +12 -11
  54. adam/commands/export/export_use.py +3 -3
  55. adam/commands/export/export_x_select.py +48 -0
  56. adam/commands/export/exporter.py +140 -53
  57. adam/commands/export/import_files.py +2 -2
  58. adam/commands/export/import_session.py +0 -4
  59. adam/commands/export/importer.py +11 -11
  60. adam/commands/export/importer_athena.py +15 -35
  61. adam/commands/export/importer_sqlite.py +19 -8
  62. adam/commands/export/show_column_counts.py +10 -10
  63. adam/commands/export/show_export_databases.py +2 -1
  64. adam/commands/export/show_export_session.py +1 -1
  65. adam/commands/export/show_export_sessions.py +1 -1
  66. adam/commands/export/utils_export.py +38 -15
  67. adam/commands/fs/__init__.py +0 -0
  68. adam/commands/{cat.py → fs/cat.py} +2 -2
  69. adam/commands/fs/cat_local.py +42 -0
  70. adam/commands/{cd.py → fs/cd.py} +2 -2
  71. adam/commands/{download_file.py → fs/download_file.py} +5 -5
  72. adam/commands/{find_files.py → fs/find_files.py} +4 -4
  73. adam/commands/{find_processes.py → fs/find_processes.py} +3 -3
  74. adam/commands/{head.py → fs/head.py} +2 -2
  75. adam/commands/{ls.py → fs/ls.py} +2 -2
  76. adam/commands/fs/ls_local.py +40 -0
  77. adam/commands/fs/rm.py +18 -0
  78. adam/commands/fs/rm_downloads.py +39 -0
  79. adam/commands/fs/rm_logs.py +38 -0
  80. adam/commands/{show → fs}/show_adam.py +1 -1
  81. adam/commands/intermediate_command.py +3 -0
  82. adam/commands/medusa/medusa_restore.py +2 -16
  83. adam/commands/medusa/utils_medusa.py +15 -0
  84. adam/commands/nodetool/__init__.py +0 -0
  85. adam/commands/{nodetool.py → nodetool/nodetool.py} +3 -8
  86. adam/commands/postgres/completions_p.py +22 -0
  87. adam/commands/postgres/postgres.py +7 -14
  88. adam/commands/postgres/postgres_databases.py +3 -3
  89. adam/commands/postgres/postgres_ls.py +1 -1
  90. adam/commands/postgres/utils_postgres.py +12 -2
  91. adam/commands/preview_table.py +1 -1
  92. adam/commands/reaper/reaper_schedule_activate.py +6 -2
  93. adam/commands/reaper/reaper_schedule_start.py +1 -2
  94. adam/commands/reaper/reaper_schedule_stop.py +1 -2
  95. adam/commands/reaper/utils_reaper.py +10 -1
  96. adam/commands/repair/repair_scan.py +0 -2
  97. adam/commands/repair/repair_stop.py +0 -1
  98. adam/commands/{show/show.py → show.py} +12 -11
  99. adam/config.py +4 -5
  100. adam/embedded_params.py +1 -1
  101. adam/repl.py +22 -9
  102. adam/repl_commands.py +50 -42
  103. adam/repl_session.py +9 -1
  104. adam/repl_state.py +16 -1
  105. adam/sql/async_executor.py +62 -0
  106. adam/sql/lark_completer.py +286 -0
  107. adam/sql/lark_parser.py +604 -0
  108. adam/sql/qingl.lark +1076 -0
  109. adam/sso/cred_cache.py +2 -5
  110. adam/utils.py +216 -79
  111. adam/utils_k8s/app_clusters.py +11 -4
  112. adam/utils_k8s/app_pods.py +10 -5
  113. adam/utils_k8s/cassandra_clusters.py +8 -4
  114. adam/utils_k8s/cassandra_nodes.py +14 -5
  115. adam/utils_k8s/k8s.py +9 -0
  116. adam/utils_k8s/kube_context.py +1 -4
  117. adam/{pod_exec_result.py → utils_k8s/pod_exec_result.py} +8 -2
  118. adam/utils_k8s/pods.py +83 -24
  119. adam/utils_k8s/statefulsets.py +5 -2
  120. adam/utils_local.py +78 -2
  121. adam/utils_repl/appendable_completer.py +6 -0
  122. adam/utils_repl/repl_completer.py +51 -4
  123. adam/utils_sqlite.py +3 -8
  124. adam/version.py +1 -1
  125. {kaqing-2.0.184.dist-info → kaqing-2.0.214.dist-info}/METADATA +1 -1
  126. kaqing-2.0.214.dist-info/RECORD +272 -0
  127. kaqing-2.0.214.dist-info/top_level.txt +2 -0
  128. teddy/__init__.py +0 -0
  129. teddy/lark_parser.py +436 -0
  130. teddy/lark_parser2.py +618 -0
  131. adam/commands/cql/cql_completions.py +0 -32
  132. adam/commands/export/export_select_x.py +0 -54
  133. adam/commands/logs.py +0 -37
  134. adam/commands/postgres/psql_completions.py +0 -11
  135. adam/commands/report.py +0 -61
  136. adam/commands/restart.py +0 -60
  137. adam/commands/show/show_processes.py +0 -49
  138. kaqing-2.0.184.dist-info/RECORD +0 -244
  139. kaqing-2.0.184.dist-info/top_level.txt +0 -1
  140. /adam/commands/{login.py → app/login.py} +0 -0
  141. /adam/commands/{show → cassandra}/__init__.py +0 -0
  142. /adam/commands/{show → cassandra}/show_cassandra_version.py +0 -0
  143. /adam/commands/{watch.py → cassandra/watch.py} +0 -0
  144. /adam/commands/{param_get.py → config/param_get.py} +0 -0
  145. /adam/commands/{param_set.py → config/param_set.py} +0 -0
  146. /adam/commands/{issues.py → diag/issues.py} +0 -0
  147. /adam/commands/{pwd.py → fs/pwd.py} +0 -0
  148. /adam/commands/{shell.py → fs/shell.py} +0 -0
  149. /adam/commands/{show → fs}/show_host.py +0 -0
  150. /adam/commands/{nodetool_commands.py → nodetool/nodetool_commands.py} +0 -0
  151. {kaqing-2.0.184.dist-info → kaqing-2.0.214.dist-info}/WHEEL +0 -0
  152. {kaqing-2.0.184.dist-info → kaqing-2.0.214.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,286 @@
1
+ import functools
2
+ import os
3
+ from typing import Iterable
4
+ from prompt_toolkit.completion import CompleteEvent, Completer, Completion, NestedCompleter, WordCompleter
5
+ from prompt_toolkit.document import Document
6
+
7
+ from adam.config import Config
8
+ from adam.sql.async_executor import AsyncExecutor
9
+ from adam.sql.lark_parser import LarkParser
10
+ from adam.utils import debug, log_timing, offload
11
+ from adam.utils_repl.appendable_completer import AppendableCompleter
12
+ from adam.utils_repl.repl_completer import merge_completions
13
+
14
+ __all__ = [
15
+ "LarkCompleter",
16
+ ]
17
+
18
+ def default_columns(x: list[str]):
19
+ return 'id,x.,y.,z.'.split(',')
20
+
21
+ class LarkCompleter(Completer, AppendableCompleter):
22
+ SYSTEM = 'system'
23
+
24
+ def __init__(self,
25
+ dml: str = None,
26
+ expandables: dict = {},
27
+ variant: str = 'c',
28
+
29
+ name: str = None,
30
+ options_lambda: callable = None,
31
+ auto: str = 'lazy',
32
+ debug = False
33
+ ) -> None:
34
+ self.nested: NestedCompleter = None
35
+ self.options_lambda = options_lambda
36
+ if options_lambda and auto == 'lazy':
37
+ AsyncExecutor.preload(options_lambda, log_key=name)
38
+
39
+ self.variant = variant
40
+ self.parser = None
41
+ self.dml = dml
42
+ self.expandables = expandables
43
+
44
+ self.display_dict = {}
45
+ self.meta_dict = {}
46
+ self.WORD = None
47
+ self.sentence = False
48
+ self.match_middle = False
49
+ self.pattern = None
50
+
51
+ self.debug = debug
52
+
53
+ if variant:
54
+ self.parser = LarkCompleter.lark_parser(variant)
55
+ self.preload_lazy_auto_completes()
56
+
57
+ def __repr__(self):
58
+ return f"LarkCompleter.{self.variant}"
59
+
60
+ def preload_lazy_auto_completes(self):
61
+ for key, value in self.expandables.items():
62
+ if callable(value):
63
+ if self.auto_complete(key) == 'lazy':
64
+ AsyncExecutor.preload(value, log_key=key)
65
+
66
+ def from_lambda(name: str, options_lambda: callable, auto: str = 'lazy'):
67
+ return LarkCompleter(name=name, options_lambda=options_lambda, auto=auto, variant=None)
68
+
69
+ @functools.lru_cache()
70
+ def lark_parser(variant: str):
71
+ dir_path = os.path.dirname(os.path.realpath(__file__))
72
+ with open(dir_path + f"/qingl.lark") as f:
73
+ grammar: str = None
74
+ with log_timing(f'lark.{variant}.file-read'):
75
+ grammar = f.read()
76
+
77
+ common_contexts = {
78
+ 'cd_command.file_name': 'direct-dirs',
79
+ }
80
+
81
+ if variant in ['a', 'c0', 'p0', 'x0']:
82
+ grammar = grammar.replace('start: statement_sequence', f'start: qing_{variant}_statement')
83
+ contexts_by_path = {
84
+ } | common_contexts
85
+
86
+ debug(f'* GRAMMAR replaced to start: qing_{variant}_statement')
87
+
88
+ return LarkParser(grammar, contexts_by_path)
89
+ elif variant == 'system':
90
+ grammar = grammar.replace('start: statement_sequence', f'start: qing_{variant}_statement')
91
+ contexts_by_path = {
92
+ } | common_contexts
93
+
94
+ return LarkParser(grammar, contexts_by_path)
95
+
96
+ grammar = grammar.replace('qing_statement: qing_p_statement', f'qing_statement: qing_{variant}_statement')
97
+ debug(f'* GRAMMAR replaced to qing_statement: qing_{variant}_statement')
98
+
99
+ bash_contexts = {
100
+ 'bash_statement.host_name': 'hosts',
101
+ 'bash_statement.bash_command': 'bash-commands',
102
+ }
103
+
104
+ contexts_by_path = {
105
+ 'describe_keyspace.keyspace_name': 'keyspaces',
106
+ 'keyspace_ref.keyspace_path.namespace_ref.identifier_ref': 'tables',
107
+ 'preview_table_statement.path.identifier_ref': 'tables',
108
+
109
+ 'insert_statement.insert_select': 'column-names',
110
+ 'update_statement.set_clause.path.identifier_ref': 'column-names',
111
+ 'update_statement.where_clause.cond.expr.path.identifier_ref': 'column-names',
112
+ 'delete_statement.where_clause.cond.expr.path.identifier_ref': 'column-names',
113
+
114
+ 'select_clause.projection.result_expr.expr.path.identifier_ref': 'columns',
115
+ 'select_from.where_clause.cond.expr.path.identifier_ref': 'columns',
116
+ 'select_from.where_clause.cond.expr.logical_term.and_expr.cond.expr.path.identifier_ref': 'columns',
117
+ 'select_from.group_by_clause.group_term.expr.path.identifier_ref': 'columns',
118
+ 'select_statement.order_by_clause.ordering_term.expr.path.identifier_ref': 'columns',
119
+ 'select_from.from_clause.from_terms.join_clause.ansi_join_clause.ansi_join_predicate.expr.path.identifier_ref': 'columns',
120
+ 'select_from.from_clause.from_terms.join_clause.ansi_join_clause.ansi_join_predicate.expr.comparison_term.relational_expr.expr.path.identifier_ref': 'columns',
121
+
122
+ 'select_from.from_clause.from_terms.from_generic.alias.identifier_ref': 'column-aliases',
123
+
124
+ 'select_statement.limit_clause.expr.literal.nbr.digit': 'limits',
125
+ } | common_contexts
126
+
127
+ if variant == 'p':
128
+ contexts_by_path = bash_contexts | contexts_by_path
129
+ elif variant == 'c':
130
+ contexts_by_path = {
131
+ 'export_table.path.identifier_ref': 'tables',
132
+ 'show_column_counts_command.path.identifier_ref': 'tables',
133
+ 'export_statement.export_tables.keyspace_name': 'keyspaces',
134
+
135
+ 'alter_tables_statement.properties.property.property_name': 'table-props',
136
+ 'alter_cql_table_statement.properties.property.property_name': 'table-props',
137
+ 'alter_tables_statement.properties.property.property_value.literal': 'table-props-value',
138
+ 'alter_cql_table_statement.properties.property.property_value.literal': 'table-props-value',
139
+
140
+ 'select_clause.projection.result_expr.expr.path.identifier_ref': 'columns',
141
+ 'export_statement.export_tables.export_table.column_name_list.column_name': 'columns',
142
+
143
+ 'consistency_statement.consistency': 'consistencies',
144
+ 'export_statement.export_to.export_database_type': 'export-database-types',
145
+ 'drop_export_database.export_database_name': 'export-databases',
146
+ 'use_export_db_statement.export_database_name': 'export-databases',
147
+ 'clean_up_export_session_statement.clean_up_export_sessions.export_session_name': 'export-sessions',
148
+ 'show_export_command.export_session_name': 'export-sessions',
149
+ 'import_statement.import_session.export_session_name': 'export-sessions-incomplete',
150
+ 'download_session_statement.export_session_name': 'export-sessions-incomplete',
151
+ } | bash_contexts | contexts_by_path
152
+ elif variant == 'l':
153
+ contexts_by_path = {
154
+ 'add_partition_action.partition_ref.partition_name': 'partition-columns',
155
+ 'show_topn_statement.topn_count': 'topn-counts',
156
+ 'show_topn_statement.topn_type': 'topn-types',
157
+ 'show_topn_statement.topn_window': 'topn-windows'
158
+ } | contexts_by_path
159
+ elif variant == 'x':
160
+ contexts_by_path = {
161
+ 'show_column_counts_command.path.identifier_ref': 'tables',
162
+ 'drop_export_database.export_database_name': 'export-databases',
163
+ 'use_export_db_statement.export_database_name': 'export-databases',
164
+ } | contexts_by_path
165
+
166
+ grammar = grammar.replace('select_clause: "SELECT"i hint_comment? projection', 'select_clause: ("SELECT"i | "XELECT"i) hint_comment? projection')
167
+
168
+ with offload():
169
+ with open('/tmp/grammar.lark', 'wt') as f:
170
+ f.write(grammar)
171
+
172
+ return LarkParser(grammar, contexts_by_path)
173
+
174
+ def get_completions(
175
+ self, document: Document, complete_event: CompleteEvent
176
+ ) -> Iterable[Completion]:
177
+ if not self.nested and self.options_lambda:
178
+ # for lazy completions
179
+ self.nested = NestedCompleter.from_nested_dict(self.options_lambda())
180
+
181
+ nested_words = set()
182
+
183
+ if self.nested:
184
+ # from NestedCompleter
185
+
186
+ # Split document.
187
+ text = document.text_before_cursor.lstrip()
188
+ stripped_len = len(document.text_before_cursor) - len(text)
189
+
190
+ # If there is a space, check for the first term, and use a
191
+ # subcompleter.
192
+ if " " in text:
193
+ first_term = text.split()[0]
194
+ completer = self.nested.options.get(first_term)
195
+
196
+ # If we have a sub completer, use this for the completions.
197
+ if completer is not None:
198
+ remaining_text = text[len(first_term) :].lstrip()
199
+ move_cursor = len(text) - len(remaining_text) + stripped_len
200
+
201
+ new_document = Document(
202
+ remaining_text,
203
+ cursor_position=document.cursor_position - move_cursor,
204
+ )
205
+
206
+ for c in completer.get_completions(new_document, complete_event):
207
+ nested_words.add(c.text)
208
+ yield c
209
+
210
+ # No space in the input: behave exactly like `WordCompleter`.
211
+ else:
212
+ completer = WordCompleter(
213
+ list(self.nested.options.keys()), ignore_case=self.nested.ignore_case
214
+ )
215
+ for c in completer.get_completions(document, complete_event):
216
+ nested_words.add(c.text)
217
+ yield c
218
+
219
+ if self.parser:
220
+ full = document.text_before_cursor
221
+ if self.dml:
222
+ full = self.dml + ' ' + full
223
+
224
+ words0 = []
225
+ words1 = []
226
+ context = {}
227
+ for word in self.parser.next_terminals(full, context=context):
228
+ if ex := self.expandable(word):
229
+ if ex in self.expandables:
230
+ e = self.expandables[ex]
231
+ if callable(e):
232
+ if self.auto_complete(ex) != 'off':
233
+ ctx = None
234
+ if 'last-id' in context:
235
+ ctx = context['last-id']
236
+ e = e(ctx)
237
+ words0.extend(e)
238
+ else:
239
+ words0.extend(e)
240
+ else:
241
+ words1.append(word)
242
+ words = words0 + words1
243
+
244
+ word_before_cursor = document.get_word_before_cursor(
245
+ WORD=self.WORD, pattern=self.pattern
246
+ )
247
+
248
+ word_before_cursor = word_before_cursor.lower()
249
+
250
+ def word_matches(word: str) -> bool:
251
+ return word.lower().startswith(word_before_cursor)
252
+
253
+ for word in words:
254
+ if word_matches(word) and word not in nested_words:
255
+ display = self.display_dict.get(word, word)
256
+ display_meta = self.meta_dict.get(word, "")
257
+ yield Completion(
258
+ word,
259
+ -len(word_before_cursor),
260
+ display=display,
261
+ display_meta=display_meta,
262
+ )
263
+
264
+ def completions_for_nesting(self, dml: str = None):
265
+ if dml:
266
+ return {dml: LarkCompleter(dml, expandables=self.expandables, variant=self.variant)}
267
+
268
+ return {
269
+ word.text.lower(): LarkCompleter(word.text, expandables=self.expandables, variant=self.variant)
270
+ for word in self.get_completions(Document(''), None)
271
+ }
272
+
273
+ def expandable(self, word: str):
274
+ return word.strip('`') if word.startswith('`') else None
275
+
276
+ def append_completions(self, key: str, value: dict[str, any]):
277
+ if isinstance(value, LarkCompleter) and self.variant == value.variant:
278
+ return
279
+
280
+ if self.nested:
281
+ self.nested = NestedCompleter.from_nested_dict(merge_completions(self.nested.options, value))
282
+ else:
283
+ self.nested = NestedCompleter.from_nested_dict(value)
284
+
285
+ def auto_complete(self, key: str, default = 'lazy'):
286
+ return Config().get(f'auto-complete.{self.variant}.{key}', default=default)