kaqing 2.0.110__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 (251) hide show
  1. adam/__init__.py +0 -2
  2. adam/app_session.py +9 -12
  3. adam/apps.py +18 -4
  4. adam/batch.py +19 -19
  5. adam/checks/check_utils.py +16 -46
  6. adam/checks/cpu.py +7 -1
  7. adam/checks/cpu_metrics.py +52 -0
  8. adam/checks/disk.py +2 -3
  9. adam/columns/columns.py +3 -1
  10. adam/columns/cpu.py +3 -1
  11. adam/columns/cpu_metrics.py +22 -0
  12. adam/columns/memory.py +3 -4
  13. adam/commands/__init__.py +24 -0
  14. adam/commands/app/app.py +38 -0
  15. adam/commands/{app_ping.py → app/app_ping.py} +7 -13
  16. adam/commands/{login.py → app/login.py} +22 -24
  17. adam/commands/app/show_app_actions.py +49 -0
  18. adam/commands/{show → app}/show_app_id.py +8 -11
  19. adam/commands/{show → app}/show_app_queues.py +7 -14
  20. adam/commands/app/show_login.py +56 -0
  21. adam/commands/app/utils_app.py +106 -0
  22. adam/commands/audit/audit.py +22 -40
  23. adam/commands/audit/audit_repair_tables.py +15 -19
  24. adam/commands/audit/audit_run.py +15 -22
  25. adam/commands/audit/completions_l.py +15 -0
  26. adam/commands/audit/show_last10.py +4 -18
  27. adam/commands/audit/show_slow10.py +4 -17
  28. adam/commands/audit/show_top10.py +4 -16
  29. adam/commands/audit/utils_show_top10.py +15 -3
  30. adam/commands/bash/__init__.py +5 -0
  31. adam/commands/bash/bash.py +36 -0
  32. adam/commands/bash/bash_completer.py +93 -0
  33. adam/commands/bash/utils_bash.py +16 -0
  34. adam/commands/cassandra/__init__.py +0 -0
  35. adam/commands/cassandra/download_cassandra_log.py +45 -0
  36. adam/commands/{restart.py → cassandra/restart_cluster.py} +12 -26
  37. adam/commands/cassandra/restart_node.py +51 -0
  38. adam/commands/cassandra/restart_nodes.py +47 -0
  39. adam/commands/{rollout.py → cassandra/rollout.py} +20 -25
  40. adam/commands/cassandra/show_cassandra_repairs.py +37 -0
  41. adam/commands/cassandra/show_cassandra_status.py +117 -0
  42. adam/commands/{show → cassandra}/show_cassandra_version.py +5 -18
  43. adam/commands/cassandra/show_processes.py +50 -0
  44. adam/commands/cassandra/show_storage.py +44 -0
  45. adam/commands/{watch.py → cassandra/watch.py} +26 -29
  46. adam/commands/cli/__init__.py +0 -0
  47. adam/commands/{cli_commands.py → cli/cli_commands.py} +8 -4
  48. adam/commands/cli/clipboard_copy.py +86 -0
  49. adam/commands/cli/show_cli_commands.py +56 -0
  50. adam/commands/code.py +57 -0
  51. adam/commands/command.py +211 -40
  52. adam/commands/commands_utils.py +20 -27
  53. adam/commands/config/__init__.py +0 -0
  54. adam/commands/{param_get.py → config/param_get.py} +11 -14
  55. adam/commands/{param_set.py → config/param_set.py} +8 -12
  56. adam/commands/{show → config}/show_params.py +2 -5
  57. adam/commands/cql/alter_tables.py +66 -0
  58. adam/commands/cql/completions_c.py +29 -0
  59. adam/commands/cql/cqlsh.py +10 -32
  60. adam/commands/cql/utils_cql.py +306 -0
  61. adam/commands/debug/__init__.py +0 -0
  62. adam/commands/debug/debug.py +22 -0
  63. adam/commands/debug/debug_completes.py +35 -0
  64. adam/commands/debug/debug_timings.py +35 -0
  65. adam/commands/debug/show_offloaded_completes.py +45 -0
  66. adam/commands/deploy/code_start.py +7 -10
  67. adam/commands/deploy/code_stop.py +4 -21
  68. adam/commands/deploy/code_utils.py +3 -3
  69. adam/commands/deploy/deploy.py +4 -27
  70. adam/commands/deploy/deploy_frontend.py +14 -17
  71. adam/commands/deploy/deploy_pg_agent.py +3 -6
  72. adam/commands/deploy/deploy_pod.py +65 -73
  73. adam/commands/deploy/deploy_utils.py +14 -24
  74. adam/commands/deploy/undeploy.py +4 -27
  75. adam/commands/deploy/undeploy_frontend.py +4 -7
  76. adam/commands/deploy/undeploy_pg_agent.py +6 -8
  77. adam/commands/deploy/undeploy_pod.py +11 -12
  78. adam/commands/devices/__init__.py +0 -0
  79. adam/commands/devices/device.py +149 -0
  80. adam/commands/devices/device_app.py +163 -0
  81. adam/commands/devices/device_auit_log.py +49 -0
  82. adam/commands/devices/device_cass.py +179 -0
  83. adam/commands/devices/device_export.py +87 -0
  84. adam/commands/devices/device_postgres.py +160 -0
  85. adam/commands/devices/devices.py +25 -0
  86. adam/commands/diag/__init__.py +0 -0
  87. adam/commands/{check.py → diag/check.py} +16 -25
  88. adam/commands/diag/generate_report.py +52 -0
  89. adam/commands/diag/issues.py +43 -0
  90. adam/commands/exit.py +1 -4
  91. adam/commands/export/__init__.py +0 -0
  92. adam/commands/export/clean_up_all_export_sessions.py +37 -0
  93. adam/commands/export/clean_up_export_sessions.py +39 -0
  94. adam/commands/export/completions_x.py +11 -0
  95. adam/commands/export/download_export_session.py +40 -0
  96. adam/commands/export/drop_export_database.py +39 -0
  97. adam/commands/export/drop_export_databases.py +37 -0
  98. adam/commands/export/export.py +37 -0
  99. adam/commands/export/export_databases.py +251 -0
  100. adam/commands/export/export_select.py +34 -0
  101. adam/commands/export/export_sessions.py +210 -0
  102. adam/commands/export/export_use.py +49 -0
  103. adam/commands/export/export_x_select.py +48 -0
  104. adam/commands/export/exporter.py +419 -0
  105. adam/commands/export/import_files.py +44 -0
  106. adam/commands/export/import_session.py +40 -0
  107. adam/commands/export/importer.py +81 -0
  108. adam/commands/export/importer_athena.py +157 -0
  109. adam/commands/export/importer_sqlite.py +78 -0
  110. adam/commands/export/show_column_counts.py +45 -0
  111. adam/commands/export/show_export_databases.py +39 -0
  112. adam/commands/export/show_export_session.py +39 -0
  113. adam/commands/export/show_export_sessions.py +37 -0
  114. adam/commands/export/utils_export.py +366 -0
  115. adam/commands/fs/__init__.py +0 -0
  116. adam/commands/fs/cat.py +36 -0
  117. adam/commands/fs/cat_local.py +42 -0
  118. adam/commands/fs/cd.py +41 -0
  119. adam/commands/fs/download_file.py +47 -0
  120. adam/commands/fs/find_files.py +51 -0
  121. adam/commands/fs/find_processes.py +76 -0
  122. adam/commands/fs/head.py +36 -0
  123. adam/commands/fs/ls.py +41 -0
  124. adam/commands/fs/ls_local.py +40 -0
  125. adam/commands/fs/pwd.py +45 -0
  126. adam/commands/fs/rm.py +18 -0
  127. adam/commands/fs/rm_downloads.py +39 -0
  128. adam/commands/fs/rm_logs.py +38 -0
  129. adam/commands/{shell.py → fs/shell.py} +12 -4
  130. adam/commands/{show → fs}/show_adam.py +3 -3
  131. adam/commands/{show → fs}/show_host.py +1 -1
  132. adam/commands/help.py +5 -3
  133. adam/commands/intermediate_command.py +52 -0
  134. adam/commands/kubectl.py +38 -0
  135. adam/commands/medusa/medusa.py +4 -22
  136. adam/commands/medusa/medusa_backup.py +20 -27
  137. adam/commands/medusa/medusa_restore.py +35 -48
  138. adam/commands/medusa/medusa_show_backupjobs.py +16 -18
  139. adam/commands/medusa/medusa_show_restorejobs.py +13 -18
  140. adam/commands/medusa/utils_medusa.py +15 -0
  141. adam/commands/nodetool/__init__.py +0 -0
  142. adam/commands/{nodetool.py → nodetool/nodetool.py} +9 -20
  143. adam/commands/postgres/completions_p.py +22 -0
  144. adam/commands/postgres/postgres.py +47 -55
  145. adam/commands/postgres/postgres_databases.py +269 -0
  146. adam/commands/postgres/postgres_ls.py +5 -9
  147. adam/commands/postgres/postgres_preview.py +5 -9
  148. adam/commands/postgres/utils_postgres.py +80 -0
  149. adam/commands/preview_table.py +8 -44
  150. adam/commands/reaper/reaper.py +4 -27
  151. adam/commands/reaper/reaper_forward.py +49 -56
  152. adam/commands/reaper/reaper_forward_session.py +6 -0
  153. adam/commands/reaper/reaper_forward_stop.py +10 -16
  154. adam/commands/reaper/reaper_restart.py +7 -14
  155. adam/commands/reaper/reaper_run_abort.py +8 -33
  156. adam/commands/reaper/reaper_runs.py +43 -58
  157. adam/commands/reaper/reaper_runs_abort.py +29 -49
  158. adam/commands/reaper/reaper_schedule_activate.py +14 -33
  159. adam/commands/reaper/reaper_schedule_start.py +9 -33
  160. adam/commands/reaper/reaper_schedule_stop.py +9 -33
  161. adam/commands/reaper/reaper_schedules.py +4 -14
  162. adam/commands/reaper/reaper_status.py +8 -16
  163. adam/commands/reaper/utils_reaper.py +203 -0
  164. adam/commands/repair/repair.py +4 -22
  165. adam/commands/repair/repair_log.py +5 -11
  166. adam/commands/repair/repair_run.py +27 -34
  167. adam/commands/repair/repair_scan.py +32 -40
  168. adam/commands/repair/repair_stop.py +5 -12
  169. adam/commands/show.py +40 -0
  170. adam/config.py +5 -15
  171. adam/embedded_params.py +1 -1
  172. adam/log.py +4 -4
  173. adam/repl.py +83 -116
  174. adam/repl_commands.py +86 -45
  175. adam/repl_session.py +9 -1
  176. adam/repl_state.py +176 -40
  177. adam/sql/async_executor.py +62 -0
  178. adam/sql/lark_completer.py +286 -0
  179. adam/sql/lark_parser.py +604 -0
  180. adam/sql/qingl.lark +1076 -0
  181. adam/sql/sql_completer.py +52 -27
  182. adam/sql/sql_state_machine.py +131 -19
  183. adam/sso/authn_ad.py +6 -8
  184. adam/sso/authn_okta.py +4 -6
  185. adam/sso/cred_cache.py +4 -9
  186. adam/sso/idp.py +9 -12
  187. adam/utils.py +670 -31
  188. adam/utils_athena.py +145 -0
  189. adam/utils_audits.py +12 -103
  190. adam/utils_issues.py +32 -0
  191. adam/utils_k8s/app_clusters.py +35 -0
  192. adam/utils_k8s/app_pods.py +41 -0
  193. adam/utils_k8s/cassandra_clusters.py +35 -20
  194. adam/utils_k8s/cassandra_nodes.py +15 -6
  195. adam/utils_k8s/custom_resources.py +16 -17
  196. adam/utils_k8s/ingresses.py +2 -2
  197. adam/utils_k8s/jobs.py +7 -11
  198. adam/utils_k8s/k8s.py +96 -0
  199. adam/utils_k8s/kube_context.py +3 -6
  200. adam/{pod_exec_result.py → utils_k8s/pod_exec_result.py} +13 -4
  201. adam/utils_k8s/pods.py +159 -89
  202. adam/utils_k8s/secrets.py +4 -4
  203. adam/utils_k8s/service_accounts.py +5 -4
  204. adam/utils_k8s/services.py +2 -2
  205. adam/utils_k8s/statefulsets.py +6 -14
  206. adam/utils_local.py +80 -0
  207. adam/utils_net.py +4 -4
  208. adam/utils_repl/__init__.py +0 -0
  209. adam/utils_repl/appendable_completer.py +6 -0
  210. adam/utils_repl/automata_completer.py +48 -0
  211. adam/utils_repl/repl_completer.py +93 -0
  212. adam/utils_repl/state_machine.py +173 -0
  213. adam/utils_sqlite.py +132 -0
  214. adam/version.py +1 -1
  215. {kaqing-2.0.110.dist-info → kaqing-2.0.214.dist-info}/METADATA +1 -1
  216. kaqing-2.0.214.dist-info/RECORD +272 -0
  217. kaqing-2.0.214.dist-info/top_level.txt +2 -0
  218. teddy/__init__.py +0 -0
  219. teddy/lark_parser.py +436 -0
  220. teddy/lark_parser2.py +618 -0
  221. adam/commands/alter_tables.py +0 -81
  222. adam/commands/app.py +0 -67
  223. adam/commands/bash.py +0 -150
  224. adam/commands/cd.py +0 -125
  225. adam/commands/cp.py +0 -95
  226. adam/commands/cql/cql_completions.py +0 -15
  227. adam/commands/cql/cql_utils.py +0 -112
  228. adam/commands/devices.py +0 -118
  229. adam/commands/issues.py +0 -75
  230. adam/commands/logs.py +0 -40
  231. adam/commands/ls.py +0 -146
  232. adam/commands/postgres/postgres_context.py +0 -239
  233. adam/commands/postgres/postgres_utils.py +0 -31
  234. adam/commands/postgres/psql_completions.py +0 -10
  235. adam/commands/pwd.py +0 -77
  236. adam/commands/reaper/reaper_session.py +0 -159
  237. adam/commands/report.py +0 -63
  238. adam/commands/show/show.py +0 -54
  239. adam/commands/show/show_app_actions.py +0 -56
  240. adam/commands/show/show_cassandra_status.py +0 -128
  241. adam/commands/show/show_commands.py +0 -61
  242. adam/commands/show/show_login.py +0 -63
  243. adam/commands/show/show_processes.py +0 -53
  244. adam/commands/show/show_repairs.py +0 -47
  245. adam/commands/show/show_storage.py +0 -52
  246. kaqing-2.0.110.dist-info/RECORD +0 -187
  247. kaqing-2.0.110.dist-info/top_level.txt +0 -1
  248. /adam/commands/{show → app}/__init__.py +0 -0
  249. /adam/commands/{nodetool_commands.py → nodetool/nodetool_commands.py} +0 -0
  250. {kaqing-2.0.110.dist-info → kaqing-2.0.214.dist-info}/WHEEL +0 -0
  251. {kaqing-2.0.110.dist-info → kaqing-2.0.214.dist-info}/entry_points.txt +0 -0
teddy/lark_parser2.py ADDED
@@ -0,0 +1,618 @@
1
+ from copy import copy
2
+ from typing import Union
3
+ import unittest
4
+ from lark import Lark, Token, Tree
5
+ from lark.grammar import NonTerminal, Terminal
6
+
7
+ class GNode:
8
+ def __init__(self, name: str, token: Token = None, choices: dict[int, int] = {}):
9
+ self.name = name
10
+ self.token = token
11
+ self.choices = choices
12
+
13
+ def __eq__(self, other: 'GNode'):
14
+ return self.__repr__() == other.__repr__()
15
+
16
+ def __hash__(self):
17
+ return hash(self.__repr__())
18
+
19
+ def __repr__(self):
20
+ n = self.name if self.name else f'{self.token}'
21
+ if self.choices:
22
+ # print(self.choices, self.choices_to_list())
23
+ choices = self.choices_to_list()
24
+ n = f'{n}-{"-".join([f"{c}" for c in choices])}'
25
+
26
+ return n
27
+
28
+ def pname(self):
29
+ return self.name if self.name else f'{self.token}'
30
+
31
+ def choice(self, depth: int):
32
+ if depth in self.choices:
33
+ return self.choices[depth]
34
+
35
+ return -1
36
+
37
+ def set_choice(self, depth: int, choice: int):
38
+ self.choices[depth] = choice
39
+
40
+ def choices_to_list(self):
41
+ choices = []
42
+
43
+ if self.choices:
44
+ for i in range(0, max(self.choices.keys()) + 1):
45
+ if i in self.choices:
46
+ choices.append(self.choices[i])
47
+ else:
48
+ choices.append(0)
49
+
50
+ return choices
51
+
52
+ def choice_list_to_str(self):
53
+ return '-'.join([f'{c}' for c in self.choices_to_list()[:-1]])
54
+
55
+ def choice_list_to_dict(self, choices: list[int]):
56
+ return {i: c for i, c in enumerate(choices)}
57
+
58
+ def drop_last(self):
59
+ new_node = copy(self)
60
+ choices = self.choices_to_list()[:-1]
61
+ new_node.choices = self.choice_list_to_dict(choices)
62
+
63
+ return new_node
64
+
65
+ class GPath:
66
+ def __init__(self, nodes: list[GNode], complete: bool, trail: list[str] = []):
67
+ self.nodes = nodes
68
+ self.complete = complete
69
+ self.trail = trail
70
+
71
+ def __eq__(self, other: 'GPath'):
72
+ return self.__repr__() == other.__repr__()
73
+
74
+ def __hash__(self):
75
+ return hash(self.__repr__())
76
+
77
+ def __repr__(self):
78
+ return '.'.join([f'{p}' for p in self.nodes])
79
+
80
+ def token(self):
81
+ return self.nodes[-1]
82
+
83
+ def append(self, node):
84
+ new_path = copy(self)
85
+ nodes = []
86
+ for n in self.nodes:
87
+ n1 = copy(n)
88
+ ss = {}
89
+ for k, v in n.choices.items():
90
+ ss[k] = v
91
+ n1.choices = ss
92
+ nodes.append(n1)
93
+ nodes.append(node)
94
+ new_path.nodes = nodes
95
+
96
+ return new_path
97
+
98
+ def drop_last(self):
99
+ new_path = copy(self)
100
+ nodes = []
101
+ for n in self.nodes[:-1]:
102
+ nodes.append(n)
103
+ new_path.nodes = nodes
104
+
105
+ return new_path
106
+
107
+ def clone(self):
108
+ new_path = copy(self)
109
+ nodes = []
110
+ for n in self.nodes:
111
+ n1 = copy(n)
112
+ ss = {}
113
+ for k, v in n.choices.items():
114
+ ss[k] = v
115
+ n1.choices = ss
116
+ nodes.append(n1)
117
+ new_path.nodes = nodes
118
+
119
+ return new_path
120
+
121
+ def terminal(self):
122
+ last_node = self.nodes[-1]
123
+ # print('SEAN', last_node.token.data)
124
+ return last_node.pname()
125
+
126
+ def terminals(paths: set['GPath']):
127
+ return ','.join(p.terminal() for p in list(paths))
128
+
129
+ class CompletePath:
130
+ def __init__(self, path: GPath, complete: False):
131
+ self.path = path
132
+ self.complete = complete
133
+
134
+ class SeqOrUnion:
135
+ def __init__(self, collection: list, is_seq: bool):
136
+ self.collection = collection
137
+ self.is_seq = is_seq
138
+
139
+ class LarkParser:
140
+ def __init__(self):
141
+ grammar = """
142
+ start: expression
143
+ expression: term (("+" | "-") term)*
144
+ term: factor (("*" | "/") factor)*
145
+ factor: NUMBER | "(" expression ")"
146
+ NUMBER: /[0-9]+/
147
+ %ignore " "
148
+ """
149
+
150
+ parser = Lark(grammar, start='start')
151
+
152
+ # print('TEST parsing', parser.parse('(56)'))
153
+
154
+ # print(parser.grammar.term_defs)
155
+
156
+ for rule in parser.grammar.rule_defs + parser.grammar.term_defs:
157
+ lhv = rule[0]
158
+ # print(f'{lhv} :=')
159
+ # print(rule[1])
160
+ if len(rule) > 2:
161
+ tree = rule[2]
162
+ # print(f'{tree.pretty()}')
163
+ # print(rule[3])
164
+
165
+ self.rules = {rule_def[0]: rule_def[2] for rule_def in parser.grammar.rule_defs}
166
+ self.terminals = {rule_def[0]: rule_def[1] for rule_def in parser.grammar.term_defs}
167
+ self.rules_by_name1 = {rule_def[0]: rule_def[1] for rule_def in parser.grammar.rule_defs}
168
+ self.rules_by_name2 = {rule_def[0]: rule_def[3] for rule_def in parser.grammar.rule_defs}
169
+
170
+ def children_by_choices(self, tree: Tree, choices: list[int] = [], depth: int = 0):
171
+ children: dict[str, SeqOrUnion] = {}
172
+
173
+ if isinstance(tree, Token):
174
+ pass
175
+ elif isinstance(tree, Terminal):
176
+ pass
177
+ elif isinstance(tree, NonTerminal):
178
+ pass
179
+ elif isinstance(tree, tuple):
180
+ children |= self.children_by_choices(tree[0], choices, depth=depth)
181
+ elif tree.data == 'expr':
182
+ for child in tree.children[:1]:
183
+ children |= self.children_by_choices(child, choices, depth=depth)
184
+ # complete = False
185
+ elif tree.data == 'value':
186
+ # print('value')
187
+ for child in tree.children:
188
+ children |= self.children_by_choices(child, choices, depth=depth)
189
+ elif tree.data == 'literal':
190
+ # print('literal')
191
+ for child in tree.children:
192
+ children |= self.children_by_choices(child, choices, depth=depth)
193
+ elif tree.data == 'expansions':
194
+ # print('expansions')
195
+ # print(tree.pretty())
196
+ choices_str = '-'.join([f"{c}" for c in choices])
197
+ children[choices_str] = SeqOrUnion(tree.children, False)
198
+ # print(f'children_by_choices[{choices_str}] = {len(tree.children)}')
199
+ for i, child in enumerate(tree.children):
200
+ children |= self.children_by_choices(child, choices + [i], depth=depth+1)
201
+ elif tree.data == 'expansion':
202
+ # print('expansion')
203
+ # print(tree.pretty())
204
+ choices_str = '-'.join([f"{c}" for c in choices])
205
+ children[choices_str] = SeqOrUnion(tree.children, True)
206
+ # print(f'children_by_choices[{choices_str}] = {len(tree.children)}')
207
+ for i, child in enumerate(tree.children):
208
+ children |= self.children_by_choices(child, choices + [i], depth=depth+1)
209
+
210
+ return children
211
+
212
+ def find_next_terminals(self, path: GPath, debug=False):
213
+ if path == 'start':
214
+ return self.find_terminals(path, debug=debug)
215
+
216
+ if isinstance(path, set):
217
+ paths = set()
218
+
219
+ for p in list(path):
220
+ paths |= self.find_next_terminals(p, debug=debug)
221
+
222
+ return paths
223
+ elif isinstance(path, str):
224
+ path = LarkParser.build_path(path)
225
+
226
+ terminals = self.find_terminals(path, debug=debug)
227
+
228
+ next_terminals = set()
229
+
230
+ for t in terminals:
231
+ paths = self.find_next(t)
232
+ for path in paths:
233
+ terms = self.find_terminals(path, debug=debug)
234
+ for term in terms:
235
+ term.trail.append(term.terminal())
236
+ next_terminals |= terms
237
+
238
+ return next_terminals
239
+
240
+ def _find_next_terminals(self, path: GPath, debug=False):
241
+ # terminals = self.find_terminals(path)
242
+
243
+ if isinstance(path, str):
244
+ path = LarkParser.build_path(path)
245
+
246
+ next_terminals = set()
247
+
248
+ # for t in terminals:
249
+ paths = self.find_next(path)
250
+ for path in paths:
251
+ next_terminals |= self.find_terminals(path, debug=debug)
252
+
253
+ return next_terminals
254
+
255
+ def find_next(self, path: GPath, depth: int = -1, debug=False):
256
+ paths: set[GPath] = set()
257
+
258
+ if not path.nodes:
259
+ return paths
260
+
261
+ if depth == -1:
262
+ if debug: print('find_next', path)
263
+
264
+ node = path.nodes[-1]
265
+ if node.name in self.rules:
266
+ tree = self.rules[node.name]
267
+ elif node.name in self.terminals:
268
+ tree = self.terminals[node.name]
269
+ else:
270
+ tree = node.token
271
+
272
+ choices = node.choices_to_list()
273
+ children = self.children_by_choices(tree)
274
+ # print('children', children)
275
+
276
+ if depth == -1:
277
+ depth = len(choices) - 1
278
+
279
+ # print(depth, len(choices), len(children[node.choice_list_to_str()]))
280
+ # print(len(choices), len(children))
281
+ check_parent = True
282
+ if children and children[node.choice_list_to_str()].is_seq and choices[depth] + 1 < len(children[node.choice_list_to_str()].collection):
283
+ node.choices[depth] += 1
284
+ if debug: print(' move to next sibling ', path)
285
+ # print('paths', path.nodes[-1] )
286
+ paths.add(path.clone())
287
+ check_parent = False
288
+
289
+ next_sibing = children[node.choice_list_to_str()].collection[node.choices[depth]]
290
+ if next_sibing.data == 'expr':
291
+ paths |= self.find_next(path, depth, debug=debug)
292
+ check_parent = True
293
+
294
+ # print('next_sibling', next_sibing)
295
+
296
+ if check_parent:
297
+ if depth > 0:
298
+ new_node = node.drop_last()
299
+ path.nodes[-1] = new_node
300
+ if debug: print(' move up to parent tree', new_node)
301
+ depth -= 1
302
+ paths |= self.find_next(path, depth, debug=debug)
303
+ else:
304
+ path = path.drop_last()
305
+ if debug: print(' move up to parent node', path)
306
+ paths |= self.find_next(path, -1, debug=debug)
307
+
308
+ return paths
309
+
310
+ def find_terminals(self, path: GPath, paths: set[GPath] = set(), path_history: set[GNode] = set(), debug=False):
311
+ if isinstance(path, str):
312
+ path = LarkParser.build_path(path)
313
+
314
+ if debug: print('find_terminals', path)
315
+
316
+ path_history.add(path.nodes[-1])
317
+
318
+ paths = self._find_terminals(None, path, debug=debug)
319
+
320
+ new_paths = set()
321
+ for p in paths:
322
+ node = p.nodes[-1]
323
+ if node.token:
324
+ # print('found terminal node', node)
325
+ new_paths.add(p)
326
+ else:
327
+ new_paths |= self.find_terminals(p, paths, path_history, debug=debug)
328
+
329
+ return new_paths
330
+
331
+ def _find_terminals(self, tree: Tree, path: GPath, depth = 0, debug=False):
332
+ paths: set[GPath] = set()
333
+ # complete = False
334
+
335
+ node = path.nodes[-1]
336
+ if not tree:
337
+ if node.name in self.rules:
338
+ tree = self.rules[node.name]
339
+ elif node.name in self.terminals:
340
+ tree = self.terminals[node.name]
341
+ else:
342
+ tree = node.token
343
+
344
+ # print(tree)
345
+
346
+ if isinstance(tree, Token):
347
+ p = path.append(GNode(name=None, token=tree))
348
+ print('<- ', tree.value, '\t\t', p)
349
+ paths.add(p)
350
+ elif isinstance(tree, Terminal):
351
+ paths.add(path.append(GNode(tree.name)))
352
+ elif isinstance(tree, NonTerminal):
353
+ # print('non-termial', tree.name)
354
+ paths.add(path.append(GNode(tree.name)))
355
+ elif isinstance(tree, tuple):
356
+ paths |= self._find_terminals(tree[0], path, depth=depth)
357
+ elif tree.data == 'expr':
358
+ # print('expr')
359
+ for child in tree.children[:1]:
360
+ paths |= self._find_terminals(child, path, depth=depth)
361
+ elif tree.data == 'value':
362
+ # print('value')
363
+ for child in tree.children:
364
+ paths |= self._find_terminals(child, path, depth=depth)
365
+ elif tree.data == 'literal':
366
+ # print('literal')
367
+ for child in tree.children:
368
+ paths |= self._find_terminals(child, path, depth=depth)
369
+ elif tree.data == 'expansions':
370
+ if node.choice(depth) == -1:
371
+ for i, child in enumerate(tree.children):
372
+ p = path.clone()
373
+ node = p.nodes[-1]
374
+ node.set_choice(depth, i)
375
+ paths |= self._find_terminals(child, p, depth=depth+1)
376
+ else:
377
+ # node.set_choice(depth, node.choice(depth))
378
+ paths |= self._find_terminals(tree.children[node.choice(depth)], path, depth=depth+1)
379
+ elif tree.data == 'expansion':
380
+ # print('expansion', path)
381
+ if (choice := node.choice(depth)) == -1:
382
+ choice = 0
383
+
384
+ node.set_choice(depth, choice)
385
+ paths |= self._find_terminals(tree.children[choice], path, depth=depth+1)
386
+
387
+ return paths
388
+
389
+ def visit(self, path: GPath, paths: set[GPath] = set(), path_history: set[GNode] = set(), next = False):
390
+ if isinstance(path, str):
391
+ print('visit', path)
392
+ path = LarkParser.build_path(path)
393
+
394
+ # print('visit', path)
395
+ if path.nodes[-1] in path_history:
396
+ return paths
397
+
398
+ path_history.add(path.nodes[-1])
399
+
400
+ paths = self.visit_tree(None, path, next=next)
401
+
402
+ new_paths = set()
403
+ for p in paths:
404
+ node = p.nodes[-1]
405
+ if node.token:
406
+ # print('found terminal node', node)
407
+ new_paths.add(p)
408
+ else:
409
+ new_paths |= self.visit(p, paths, path_history, next=False)
410
+
411
+ return new_paths
412
+
413
+ def visit_tree(self, tree: Tree, path: GPath, depth = 0, next = False):
414
+ paths: set[GPath] = set()
415
+ # complete = False
416
+
417
+ node = path.nodes[-1]
418
+ if not tree:
419
+ if node.name in self.rules:
420
+ tree = self.rules[node.name]
421
+ elif node.name in self.terminals:
422
+ tree = self.terminals[node.name]
423
+ else:
424
+ tree = node.token
425
+
426
+ # print(tree)
427
+
428
+ if isinstance(tree, Token):
429
+ p = path.append(GNode(name=None, token=tree))
430
+ print('<- ', tree.value, '\t\t', p)
431
+ paths.add(p)
432
+ elif isinstance(tree, Terminal):
433
+ paths.add(path.append(GNode(tree.name)))
434
+ elif isinstance(tree, NonTerminal):
435
+ # print('non-termial', tree.name)
436
+ paths.add(path.append(GNode(tree.name)))
437
+ elif isinstance(tree, tuple):
438
+ paths |= self.visit_tree(tree[0], path, depth=depth)
439
+ elif tree.data == 'expr':
440
+ # print('SEAN expr', tree.data, tree.children[1])
441
+ # print('expr add extra', path)
442
+ # paths.add(path)
443
+ for child in tree.children[:1]:
444
+ paths |= self.visit_tree(child, path, depth=depth)
445
+ # complete = False
446
+ elif tree.data == 'value':
447
+ # print('value')
448
+ for child in tree.children:
449
+ paths |= self.visit_tree(child, path, depth=depth)
450
+ elif tree.data == 'literal':
451
+ # print('literal')
452
+ for child in tree.children:
453
+ paths |= self.visit_tree(child, path, depth=depth)
454
+ elif tree.data == 'expansions':
455
+ # print('expansions', path)
456
+ if next:
457
+ paths |= self.visit_tree(tree.children[node.choice(depth)], path, depth=depth+1)
458
+ else:
459
+ for i, child in enumerate(tree.children):
460
+ node.set_choice(depth, i)
461
+ paths |= self.visit_tree(child, path, depth=depth+1)
462
+ elif tree.data == 'expansion':
463
+ # print('expansion', path)
464
+ if (choice := node.choice(depth)) == -1:
465
+ choice = 0
466
+
467
+ node.set_choice(depth, choice)
468
+ paths |= self.visit_tree(tree.children[choice], path, depth=depth+1)
469
+
470
+ return paths
471
+
472
+ def _find_next(self, path: GPath, paths: set[GPath] = set(), path_history: set[GNode] = set()):
473
+ if isinstance(path, str):
474
+ print('visit_next', path)
475
+ path = LarkParser.build_path(path)
476
+
477
+ # print('visit', path)
478
+ paths: set[GPath] = set()
479
+
480
+ for i in reversed(range(1, len(path.nodes) + 1)):
481
+ path = GPath(path.nodes[:i], False)
482
+ print('testing path', path)
483
+
484
+ complete = False
485
+ next = self.find_tree_next(None, path)
486
+ if next:
487
+ for n in next:
488
+ print('visiting with next', n)
489
+ paths |= self.visit(n, paths, set(), next=True)
490
+ if n.complete:
491
+ complete = True
492
+ else:
493
+ pass
494
+ # print('SEAN not complete', n)
495
+ # if not complete:
496
+ # break
497
+ # if next.complete:
498
+ # print('SEAN complete', next.complete)
499
+ # continue
500
+ if next and not complete:
501
+ break
502
+
503
+ # else:
504
+ # break
505
+
506
+ return paths
507
+
508
+ def find_tree_next(self, tree: Tree, path: GPath, depth = 0):
509
+ print('find_tree_next', path, depth)
510
+ paths: set[GPath] = set()
511
+ # complete = False
512
+
513
+ node = path.nodes[-1]
514
+ if not tree:
515
+ if node.name in self.rules:
516
+ tree = self.rules[node.name]
517
+ elif node.name in self.terminals:
518
+ tree = self.terminals[node.name]
519
+ else:
520
+ tree = node.token
521
+
522
+ if isinstance(tree, Token):
523
+ path.complete = True
524
+ pass
525
+ # print('token found', tree.value)
526
+ elif isinstance(tree, Terminal):
527
+ path.complete = True
528
+ pass
529
+ # paths.add(path.append(GNode(tree.name)))
530
+ elif isinstance(tree, NonTerminal):
531
+ pass
532
+ # print('non-termial', tree.name)
533
+ # paths.add(path.append(GNode(tree.name)))
534
+ elif isinstance(tree, tuple):
535
+ paths |= self.find_tree_next(tree[0], path, depth=depth)
536
+ elif tree.data == 'expr':
537
+ print(" " * depth, 'expr')
538
+ paths.add(path)
539
+ for child in tree.children[:1]:
540
+ paths |= self.find_tree_next(child, path, depth=depth)
541
+ # complete = False
542
+ elif tree.data == 'value':
543
+ print(" " * depth, 'value')
544
+ for child in tree.children:
545
+ paths |= self.find_tree_next(child, path, depth=depth)
546
+ elif tree.data == 'literal':
547
+ print(" " * depth, 'literal')
548
+ for child in tree.children:
549
+ paths |= self.find_tree_next(child, path, depth=depth)
550
+ elif tree.data == 'expansions':
551
+ print(" " * depth, 'expansions')
552
+ child = tree.children[node.choice(depth)]
553
+ path = self.find_tree_next(child, path, depth=depth+1)
554
+ if node.choices[depth] + 1 < len(tree.children):
555
+ node.choices[depth] += 1
556
+
557
+ paths |= path
558
+
559
+ # for i, child in enumerate(tree.children):
560
+ # # self.set_next_choice(path.nodes[-1], depth)
561
+ # paths |= self.visit_tree_next(child, rules, terminals, path, depth=depth+1)
562
+ elif tree.data == 'expansion':
563
+ print(" " * depth, 'expansion')
564
+ child = tree.children[node.choice(depth)]
565
+ if depth < len(node.choices) -1:
566
+ path = self.find_tree_next(child, path, depth=depth+1)
567
+ if node.choices[depth] + 1 < len(tree.children):
568
+ node.choices[depth] += 1
569
+
570
+ paths |= path
571
+ # else:
572
+ # if len(tree.children) > node.choices[depth] + 1:
573
+ # node.choices[depth] += 1
574
+ # if tree.children[node.choices[depth]].data == 'expr':
575
+ # print('SEAN expr')
576
+ # # np = path.drop_last()
577
+ # # print('SEAN next choice', np)
578
+ # # paths.add(np)
579
+ # path.complete = True
580
+ # paths.add(path)
581
+
582
+ # # self.set_next_choice(node, depth)
583
+ # paths.add(path)
584
+
585
+
586
+ # print(" " * depth, 'expansion', path)
587
+ # print('SEAN expansion', tree.pretty())
588
+ # if len(tree.children) > node.choices[depth] + 1:
589
+ # # print('next child found', tree.children, depth)
590
+
591
+ # node.choices[depth] += 1
592
+ # if tree.children[node.choices[depth]].data == 'expr':
593
+ # print('SEAN expr')
594
+ # # np = path.drop_last()
595
+ # # print('SEAN next choice', np)
596
+ # # paths.add(np)
597
+ # path.complete = True
598
+ # paths.add(path)
599
+
600
+ # # self.set_next_choice(node, depth)
601
+ # paths.add(path)
602
+
603
+ # # print('SEAN returning', path)
604
+
605
+ # return paths
606
+ # else:
607
+ # path.complete = True
608
+
609
+ # print('returning', paths)
610
+ return paths
611
+
612
+ def build_path(p: str):
613
+ nodes = []
614
+ for n in p.split('.'):
615
+ name_n_choices = n.split('-')
616
+ nodes.append(GNode(name_n_choices[0], choices={int(k): int(v) for k, v in enumerate(name_n_choices[1:])}))
617
+
618
+ return GPath(nodes, False)
@@ -1,81 +0,0 @@
1
- from adam.commands.command import Command
2
- from adam.commands.cql.cql_utils import tables as get_tables, run_cql
3
- from adam.config import Config
4
- from adam.repl_state import ReplState, RequiredState
5
- from adam.utils import log2
6
-
7
- class AlterTables(Command):
8
- COMMAND = 'alter tables with'
9
-
10
- # the singleton pattern
11
- def __new__(cls, *args, **kwargs):
12
- if not hasattr(cls, 'instance'): cls.instance = super(AlterTables, cls).__new__(cls)
13
-
14
- return cls.instance
15
-
16
- def __init__(self, successor: Command=None):
17
- super().__init__(successor)
18
-
19
- def required(self):
20
- return RequiredState.CLUSTER
21
-
22
- def command(self):
23
- return AlterTables.COMMAND
24
-
25
- def run(self, cmd: str, state: ReplState):
26
- if not(args := self.args(cmd)):
27
- return super().run(cmd, state)
28
-
29
- state, args = self.apply_state(args, state)
30
- if not self.validate_state(state):
31
- return state
32
-
33
- if not args:
34
- if state.in_repl:
35
- log2('Please enter gc grace in seconds. e.g. alter gc-grace-seconds 3600')
36
- else:
37
- log2('* gc grace second is missing.')
38
- log2()
39
- Command.display_help()
40
-
41
- return 'missing-arg'
42
-
43
- args, include_reaper = Command.extract_options(args, '--include-reaper')
44
- arg_str = ' '.join(args)
45
-
46
- excludes = [e.strip(' \r\n') for e in Config().get(
47
- 'cql.alter-tables.excludes',
48
- 'system_auth,system_traces,reaper_db,system_distributed,system_views,system,system_schema,system_virtual_schema').split(',')]
49
- batching = Config().get('cql.alter-tables.batching', True)
50
- tables = get_tables(state, on_any=True)
51
- for k, v in tables.items():
52
- if k not in excludes or k == 'reaper_db' and include_reaper:
53
- if batching:
54
- # alter table <table_name> with GC_GRACE_SECONDS = <timeout>;
55
- cql = ';\n'.join([f'alter table {k}.{t} with {arg_str}' for t in v])
56
- try:
57
- run_cql(state, cql, [], show_out=Config().is_debug(), on_any=True)
58
- except Exception as e:
59
- log2(e)
60
- continue
61
- else:
62
- for t in v:
63
- try:
64
- # alter table <table_name> with GC_GRACE_SECONDS = <timeout>;
65
- cql = f'alter table {k}.{t} with {arg_str}'
66
- run_cql(state, cql, [], show_out=Config().is_debug(), on_any=True)
67
- except Exception as e:
68
- log2(e)
69
- continue
70
-
71
- log2(f'{len(v)} tables altered in {k}.')
72
-
73
- # do not continue to cql route
74
- return state
75
-
76
- def completion(self, _: ReplState) -> dict[str, any]:
77
- # auto completion is taken care of by sql completer
78
- return {}
79
-
80
- def help(self, _: ReplState) -> str:
81
- return f'{AlterTables.COMMAND} <param = value> [--include-reaper] \t alter schema on all tables'